XML,DTD:如何使顺序不重要
Posted
技术标签:
【中文标题】XML,DTD:如何使顺序不重要【英文标题】:XML, DTD: how to make the order not important 【发布时间】:2011-06-12 06:49:54 【问题描述】:我开始使用 XML 文件和解析器作为存储数据的便捷方式
我想使用 DTD 在 xml 文件到达时检查它们的结构。
这是我的 DTD 文件
< ?xml version="1.0" encoding="UTF-8"?>
< !ELEMENT document (level*)>
< !ELEMENT level (file,filelName?,fileNumber?)>
< !ELEMENT file (#PCDATA)>
< !ELEMENT filelName (#PCDATA)>
< !ELEMENT fileNumber (#PCDATA)>
(请注意,fileName 和 fileNumber 实际上是纯可选的)
和
<document>
<level>
<file>group1file01</file>
</level>
<level>
<file>group1file02</file>
<fileName>file 2</fileName>
<fileNumber>0</fileNumber>
</level>
...
因此,这一切都很好。 (我现在使用 eclipse“验证”选项来测试它)
但是在测试时我发现了一个我认为很奇怪的错误
如果我这样做了
<level>
<levelName>Level 2</levelName>
<levelNumber>0</levelNumber>
<file>group1level02</file>
</level>
更改行的顺序,Eclipse 拒绝验证它...
我想知道这是否是 Eclipse 的问题,或者顺序是否真的很重要。
如果顺序很重要,无论元素的顺序如何,我如何更改 DTD 以使其正常工作?
我无法真正更改 XML,因为我已经编写了所有 XML 文件和解析器(我知道我做错了,哈哈)。
【问题讨论】:
【参考方案1】:正如罗杰所说,只有有序列表,但您可以使用运算符 OR |
来定义所有接受的组合
<!ELEMENT level ((file,filelName?,fileNumber?)|(filelName?,fileNumber?,file))>
看here,在Choices部分有一个例子
【讨论】:
哼...我原以为它会更灵活...我不得不去||因为我必须对读取 xml 的顺序进行假设,哈哈。感谢您的解决方案 这不是一个有效的 DTD,因为它不是确定性的。即使它是有效的,它也不允许子元素以任何可能的顺序排列。【参考方案2】:在 DTD 中声明带有出现约束的无序列表通常会导致声明冗长或复杂。这样做的一个重要原因是 DTD 必须是确定性的,因此即使切换到 XML 模式也不一定有帮助。
这里是元素 <level>
的 DTD 声明,其中包含:
<file>
元素
0-1 <fileName>
元素
0-1 <fileNumber>
元素
以任何可能的顺序
代码:
<!ELEMENT level ( (file, ((fileName, fileNumber?) | (fileNumber, fileName?))?)
|(fileName, ((file, fileNumber?) | (fileNumber, file)))
|(fileNumber, ((file, fileName?) | (fileName, file))) )>
【讨论】:
【参考方案3】:如果你不太关心有效性,你可以使用ANY
关键字:
<!ELEMENT level ANY>
我遇到过类似的问题here,可能会出现这两种情况:
<Instructors>
<Lecturer>
</Lecturer>
<Professor>
</Professor>
</Instructors>
<Instructors>
<Lecturer>
</Lecturer>
<Professor>
</Professor>
</Instructors>
我找到的唯一解决方案是:
<!ELEMENT Instructors ANY>
也许有更好的解决方案,但它适用于我的特定问题。
【讨论】:
最好使用: 看来是这样。一年前,我找不到更好的主意。 看来你正在做 Jennifer Widom 的斯坦福数据库 MOOC 的 XML 练习...我来到这里是因为同样的问题 :-) 与 我不再从 xmllint 得到错误。 感谢@Suzana_K 和 Alexander_Gryanko。我在括号内的属性之后包括运算符...【参考方案4】:对于 DTD,子节点必须按照元素定义中列出的顺序出现。除非您想升级到 XSD 架构,否则无法允许其他顺序。
附录:根据@Gaim,您可以使用 (a,b,c...)|(b,a,c...) 语法提供替代订单,但这不是对于超过 3 个嵌套元素来说真的很实用,因为任意顺序允许阶乘的顺序 - 6 个用于 3 个元素,24 个用于 4 个元素,120 个用于 5 个元素 - 并且巧妙地使用 ?运算符肯定会导致奇怪情况的错误验证。
【讨论】:
它是一个非常小的系统,所以我认为更改为 XSD 不会很有趣,但我会调查一下,谢谢 不完全正确。您可以允许交替排序,您只需明确列出所有您想要允许的排序。 XML 模式和 DTD 中允许的排序规则之间没有太大区别,在模式中表达它们只是不那么痛苦。【参考方案5】:如果您可以猜测元素的子元素数量的合理上限,那么解决问题的方法非常肮脏。以 0-3 个孩子为例:
<!ELEMENT myUnorderedElement ( (option1 | option2 | option3)?, (option1 | option2 | option3)?, (option1 | option2 | option3)? >
因此,您允许元素“myUnorderedElement”拥有 0-3 个选项 1、选项 2 或选项 3 类型的子元素。
【讨论】:
以上是关于XML,DTD:如何使顺序不重要的主要内容,如果未能解决你的问题,请参考以下文章