外部子集中的XML内容错误/文档末尾的额外内容

时间:2014-03-04 15:13:57

标签: xml dtd

我有外部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内容时,我在外部子集中收到内容错误。 谢谢你的帮助!

1 个答案:

答案 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,以将IDREFauto相关联。在这种情况下,您可以执行以下操作:

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)> IDIDREFauto相关联。

如果我是对的,现在你可以有一个像这样的实例:

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>