将doctype与XML一起使用

将doctype与XML一起使用,xml,dtd,doctype,entities,Xml,Dtd,Doctype,Entities,我使用单独的.dtd文件作为自定义xml文件的doctype: names.xml <?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE name SYSTEM "names.dtd"> <names> <name> <text>Pep&eacute;</text> <creator>&lost;</crea

我使用单独的.dtd文件作为自定义xml文件的doctype:

names.xml

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE name SYSTEM "names.dtd">
<names>
    <name>
        <text>Pep&eacute;</text>
        <creator>&lost;</creator>
        <history>&lost;</history>
    </name>
    <name>
        <text>Charles</text>
        <creator>James</creator>
        <history>&lost;</history>
    </name>
</names>

政治公众人物与政治公众人物;
&迷失;
&迷失;
查尔斯
詹姆斯
&迷失;
名称。dtd

<!ELEMENT name (text, creator+, history)>
<!ELEMENT text (#PCDATA)>
<!ELEMENT creator (#PCDATA)>
<!ELEMENT history (#PCDATA)>

<!-- Placeholder/unknown history or creator name -->
<!ENTITY lost "Lost in the depths of time.">
<!ENTITY eacute "é">

但是,在尝试访问names.xml时,我遇到以下错误:

XML分析错误:未定义的实体 地点: 线 第5号,第18栏:

Pepé;
---------^
仅为澄清起见,names.xml和names.dtd位于同一目录中,使用也不起作用

当把
放在
火狐中时,这似乎是可行的(Safari也不行;它没有浏览器能做到)。如果我让您的DTD和XML加载外部DTD,那么它在xmllint中工作得很好:

$ xmllint --loaddtd names.xml 
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE names SYSTEM "names.dtd">
<names>
    <name>
        <text>Pep&eacute;</text>
        <creator>&lost;</creator>
        <history>&lost;</history>
    </name>
    <name>
        <text>Charles</text>
        <creator>James</creator>
        <history>&lost;</history>
    </name>
</names>
$xmllint--loaddtd names.xml
政治公众人物与政治公众人物;
&迷失;
&迷失;
查尔斯
詹姆斯
&迷失;

编辑:正如希沃宁在评论中指出的那样,使用DTD解析外部实体是一个很好的选择。您通常不应该在web上使用doctype或dtd。如果要验证文档,应使用单独的模式(建议用于此目的),而不是文档本身中嵌入的DTD。

如果要在Firefox中打开文档以尝试确定DTD是否正确,请不要这样做。Firefox没有通过适当的xml解析器传递xml和dtd。在IE中打开xml文档,这将使您的文档通过MSXML解析器

在IE中打开xml文档时,它将使用无效字符抛出有关DTD的错误。您需要为eacute使用字符代码,而不是字符本身。这是我要做的代码

<?xml version="1.0" encoding="ISO-8859-1"?>
<!DOCTYPE NAME SYSTEM "names.dtd">
<names>
    <name>
        <text>Pep&eacute;</text>
        <creator>&lost;</creator>
        <history>&lost;</history>
    </name>
    <name>
        <text>Charles</text>
        <creator>James</creator>
        <history>&lost;</history>
   </name>
</names>

政治公众人物与政治公众人物;
&迷失;
&迷失;
查尔斯
詹姆斯
&迷失;



如果外部DTD主题的“é”字符编码正确,则可以直接在该主题中使用该字符。默认情况下,它应为UTF-8格式;您可以通过在.dtd顶部包含一个带有不同“编码”的“文本声明”来改变这一点。(文本声明基本上与声明相同。)顺便说一句,XML解析器不包含外部引用(如DTD外部子集)是合法的,而且浏览器不允许在网页上使用它是一件好事,因为它可以启用跨站点脚本。在这种情况下,未声明的实体引用是由实现定义的。更正:Firefox使用适当的XML解析器,但实体解析器(将系统ID解析为字节流的东西)已被黑客攻击,以将外部DTD解析为零长度流。浏览器加载DTD是一个非常糟糕的主意:是的,你是对的。我想知道他们中是否有人加载了本地DTD。关于为什么DTD是个坏主意的很好的参考资料。@hsivonen更新了我的答案,加入了关于为什么DTD是个坏主意的信息;谢谢你的好文章。
<?xml version="1.0" encoding="ISO-8859-1"?>
<!DOCTYPE NAME SYSTEM "names.dtd">
<names>
    <name>
        <text>Pep&eacute;</text>
        <creator>&lost;</creator>
        <history>&lost;</history>
    </name>
    <name>
        <text>Charles</text>
        <creator>James</creator>
        <history>&lost;</history>
   </name>
</names>
<!ELEMENT name (text, creator+, history)>
<!ELEMENT text (#PCDATA)>
<!ELEMENT creator (#PCDATA)>
<!ELEMENT history (#PCDATA)>

<!ENTITY lost "Lost in the depths of time.">
<!ENTITY eacute "&#233;">