我有外部DTD的XML: XML:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE autobazar SYSTEM "autobazar.dtd">
<autobazar>
<auta>
<auto id="1">
<znacka>Chevrolet</znacka>
<model>Camaro</model>
<barva>Zluta</barva>
<rok>2003</rok>
<vin>YFA205AF7780R</vin>
<prodejce>1</prodejce>
</auto>
<auto id="2">
<znacka>Opel</znacka>
<model>Manta</model>
<barva>Cerna</barva>
<rok>1895</rok>
<vin>YFA404AE67POL</vin>
<prodejce>1</prodejce>
</auto>
</auta>
<prodejci>
<prodejce id="1">
<jmeno>Milan</jmeno>
<prijmeni>Soustal</prijmeni>
<provize>5%</provize>
</prodejce>
</prodejci>
</autobazar>
DTD:
<!ELEMENT autobazar (auta*,prodejci+)>
<!ELEMENT auta (auto*)>
<!ELEMENT auto (znacka, model, barva, rok, vin, prodejce+)>
<!ELEMENT prodejci (prodejce+)>
<!ELEMENT prodejce (jmeno, prijmeni, provize)>
<!ELEMENT znacka (#PCDATA)>
<!ELEMENT model (#PCDATA)>
<!ELEMENT barva (#PCDATA)>
<!ELEMENT rok (#PCDATA)>
<!ELEMENT vin (#PCDATA)>
<!ELEMENT jmeno (#PCDATA)>
<!ELEMENT prijmeni (#PCDATA)>
<!ELEMENT provize (#PCDATA)>
<!ATTLIST auto ID #REQUIRED>
<!ATTLIST prodejce ID #REQUIRED>
当我在验证DTD时尝试验证文档末尾的XML和Extra内容时,我在外部子集中收到内容错误。 谢谢你的帮助!
答案 0 :(得分:3)
您的DTD不正确,因为您没有指定属性的名称:
<!ATTLIST auto ???? ID #REQUIRED>
<!ATTLIST prodejce ???? ID #REQUIRED>
声明属性的语法要求您提供属性名称:
<!ATTLIST element-name attribute-name attribute-type attribute-value>
您可以通过添加名称(代码中的id
)来解决此问题:
<!ATTLIST auto id ID #REQUIRED>
<!ATTLIST prodejce id ID #REQUIRED>
XML现在可能会使用更正后的DTD进行验证。
编辑:您还需要修复一些其他问题,以便文档验证。我不确切地知道你想要达到什么目标,所以我可能根据你的期望做出可能不正确的假设:
1)由于id
被声明为类型ID
,因此它不仅不能在文件中出现多次,而且也不能以数字开头。您有两种选择:a)如果它不是ID
(不一定是唯一的),您可以将其声明为NMTOKEN
:
<!ATTLIST auto id NMTOKEN #REQUIRED>
b)如果是 ID
,并且必须是唯一的,您可以在XML实例中为其添加一个字母或下划线:
<auto id="c1">
...
2)其次,您<prodejce>
的{{1}}与第一个ID
相同。假设我们已经更正了auto
,它们不再是ID
而是1
。它仍然无效,因为c1
必须在文档中是唯一的。也许您想要的不是ID
,而是ID
,以将IDREF
与auto
相关联。在这种情况下,您可以执行以下操作:
prodecje
并在XML中使用<!ATTLIST prodejce ref IDREF #REQUIRED>
来创建关联:
ref
3)但是现在它仍然失败,因为<prodejce ref="c1">
属性被声明为ref
并且#REQUIRED
个元素在prodejce
内没有属性。也许它不应该是auto
而是#REQUIRED
?您可以通过以下方式删除此错误:声明它#IMPLIED
或添加缺少的属性,但我猜这不是您想要做的,因为有一个
4)第四个问题!元素#IMPLIED
声明为有效内容prodejce
:
(jmeno, prijmeni, provize)
这意味着必须按顺序包含这些元素,每个元素中的一个,而不包含任何其他元素。在XML文档中,您有:
<!ELEMENT prodejce (jmeno, prijmeni, provize)>
根据您的DTD,这是非法的。您的DTD别无选择,只能将整个节点放在那里:
<prodejce>1</prodejce>
它应该在那里吗?那有意义吗?如果您不想在那里,可以在DTD中将其设为可选,更改<auto id="c2">
<znacka>Opel</znacka>
<model>Manta</model>
<barva>Cerna</barva>
<rok>1895</rok>
<vin>YFA404AE67POL</vin>
<prodejce ref="c1">
<jmeno>Milan</jmeno>
<prijmeni>Soustal</prijmeni>
<provize>5%</provize>
</prodejce>
</auto>
:
+
表示<!ELEMENT auto (znacka, model, barva, rok, vin, prodejce+)>
*
但这也取决于你的约束。你就知道这是否合适。是吗?我猜你想要对<!ELEMENT auto (znacka, model, barva, rok, vin, prodejce*)>
进行外部引用(因为你首先要定义ID)。您应该从prodejce
auto
从现在起,您将使用<!ELEMENT auto (znacka, model, barva, rok, vin)>
和ID
将IDREF
与auto
相关联。
如果我是对的,现在你可以有一个像这样的实例:
prodejce
根据此DTD有效:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE autobazar SYSTEM "autobazar.dtd">
<autobazar>
<auta>
<auto id="c1">
<znacka>Chevrolet</znacka>
<model>Camaro</model>
<barva>Zluta</barva>
<rok>2003</rok>
<vin>YFA205AF7780R</vin>
</auto>
<auto id="c2">
<znacka>Opel</znacka>
<model>Manta</model>
<barva>Cerna</barva>
<rok>1895</rok>
<vin>YFA404AE67POL</vin>
</auto>
</auta>
<prodejci>
<prodejce ref="c1">
<jmeno>Milan</jmeno>
<prijmeni>Soustal</prijmeni>
<provize>5%</provize>
</prodejce>
</prodejci>
</autobazar>