元素顺序无关紧要时的DTD

时间:2011-10-19 21:08:00

标签: xml dtd

我无法弄清楚如何为XML文件编写DTD,它可以包含混合顺序的相同元素。

显示问题的小例子如下:

<root>

  <element>
    <one></one>
    <two></two>
  </element>

  <element>
    <two></two>
    <one></one>
  </element>

  <element>
    <two></two>
    <two></two>
    <two></two>
    <two></two>
    <one></one>
    <one></one>
  </element>

</root>

我的DTD:

<!ELEMENT root(element*)>
<!ELEMENT element((one*,two*)|(two*,one*))>

我找到了similar topic,但解决方案在我的情况下不起作用(我不确定我的DTD目前有什么问题)。 我收到此错误消息:

xmllint: Content model of Instructors is not determinist: ((one* , two*) | (two* , one*))

3 个答案:

答案 0 :(得分:9)

<!ELEMENT element (one|two)*>

(如果您必须至少有一个,请+。)

答案 1 :(得分:4)

您的解决方案不具有确定性,因为

<element>
    <two/>
</element>

是与两个分支匹配的案例之一:(one*, two*)(two*, one*)

就像@Cristopher所说,@ Dave的答案允许混合排序,他的答案修复了这个问题。但实际上克里斯托弗的回答是不确定性,因为在验证输入时

<element>
    <two/>
</element>

并且验证器遇到第一个<two>,它不知道它应该选择哪个分支。在读取所有<two>元素后,它才会知道此

为了在保持模型确定性的同时保持订单一致,请使用

<!ELEMENT element ( (one+, two*) | (two+, one*) )? >

这里的关键点是:1)通过使用不同的强制元素开始每个分支来保持模型的确定性2)但仍允许空<element/>最后使用?,这使得内容模型可选

答案 2 :(得分:0)

给定的DTD不是确定性的,并且xml解析器可能会出错。 (参见Section 3.2.1(规范)和Appendix E(非规范性)XML规范。原因是与SGML的兼容性,如果有人记得的话。)

在您的DTD中,空元素将匹配两个分支。戴夫的解决方案改变了DTD的含义,因为它接受了

<root>
  <element>
    <one />
    <two />
    <one />
  </element>
</root>

如果您不想这样,请确保在每个“或”分支处,您只需提前查看一个标记就可以确切地知道要采取哪一个,例如,通过编写

<!ELEMENT element ((one+, two*) | (two+, one*))? >