【问题标题】:DTD when element order does not matter元素顺序无关紧要时的 DTD
【发布时间】:2011-12-11 07:20:24
【问题描述】:

我不知道如何为可以包含混合顺序的相同元素的 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*))

【问题讨论】:

  • 在 XMLSpy 中,DTD 和 XML 文件是有效的。也许是 xmllint 中的错误?

标签: xml dtd


【解决方案1】:

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

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

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

如果您不希望这样,请确保在每个“或”分支处,您只需向前看一个标记(例如,通过书写)就可以准确地知道要使用哪个标记

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

【讨论】:

  • 这不是确定性的,所以它再次导致了与这个问题相同的问题。
  • @jasso:你当然是对的。我已经纠正了(我相信)。
  • 不,你不能这样使用关键字EMPTY。现在您允许结构 &lt;element&gt;&lt;EMPTY /&gt;&lt;/element&gt; 但不允许 &lt;element&gt;&lt;/element&gt;
  • 愚蠢的我。对不起,线路噪音。
【解决方案2】:

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

<element>
    <two/>
</element>

是匹配两个分支的情况之一:(one*, two*)(two*, one*)

就像@Cristopher 指出的那样,@Dave 的回答允许混合排序,他的回答解决了这个问题。但实际上,克里斯托弗的回答也不确定,因为在验证输入时

<element>
    <two/>
</element>

验证器遇到第一个&lt;two&gt;,它不知道应该选择哪个分支。它只有在读取所有&lt;two&gt; 元素后才知道这一点。

要在保持模型确定性的同时保持顺序一致,请使用

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

这里的关键点是:1) 通过以不同的强制元素开始每个分支来保持模型的确定性 2) 但仍然允许空的 &lt;element/&gt; 和最后的 ?,这使得内容模型成为可选的。

【讨论】:

    【解决方案3】:
    <!ELEMENT element (one|two)*>
    

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

    【讨论】:

    • 看来你并没有你想象的那么生疏 :) 谢谢。
    猜你喜欢
    • 2011-06-10
    • 2020-09-10
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-11-19
    • 1970-01-01
    相关资源
    最近更新 更多