DTD需要元素排序

alt*_*ern 13 xml dtd

我希望以dtd中定义的任何顺序列出所需元素,但不知道我该怎么做.

例如,我有以下定义:

<!ELEMENT parent (child1, child2, child3)>
Run Code Online (Sandbox Code Playgroud)

这个dtd声明将成功验证以下xml:

<parent>
   <child1></child1>
   <child2></child2>
   <child3></child3>
</parent>
Run Code Online (Sandbox Code Playgroud)

但在以下情况下,xml将不会通过验证:

<parent>
   <child2></child2>
   <child1></child1>
   <child3></child3>
</parent>
Run Code Online (Sandbox Code Playgroud)

其中一个可能的解决方案是申报

<!ELEMENT parent (child1 | child2 | child3)>
Run Code Online (Sandbox Code Playgroud)

但在这种情况下,虽然验证成功,但其中一个孩子可能会丢失.

当所需元素的列表可以按任何顺序出现时,我需要正确的dtd元素声明.

C. *_*een 11

ChrisF说你不能这样做是错误的(但是要检查规格是否值得称赞!); DevNull [现称为Daniel Haley]说你可以.

但是,有一个复杂因素:DevNull 为父级提供的内容模型违反了XML的确定性规则.非正式地,这些规则说解析器必须知道文档中每个元素匹配的内容模型中的哪个令牌,而不是预测.如果在一个元素解析器看到一个child1,它无法知道没有前瞻是否刚刚匹配的第一或第二次出现child1在DevNull的内容模型.这是一个错误(但是当发生错误时,处理器没有义务报告 - 这是一个错误,意味着"所有赌注都关闭,处理器可以在这里做任何事情,包括没有注意到任何错误").

遵循确定性规则的级的内容模型可以通过分解公共前缀来形成,因此:

<!ELEMENT parent ( 
                   (child1, ( (child2,child3)
                            | (child3,child2)))
                 | (child2, ( (child1,child3)
                            | (child3,child1)))
                 | (child3, ( (child1,child2)
                            | (child2,child1)))
                 ) >
Run Code Online (Sandbox Code Playgroud)

这比使用其他模式语言的此模型的声明更不方便,并且对于三个以上的元素,它容易出错并且手动执行非常繁琐.但是使用DTD声明所需的内容模型并非不可能.或许我应该说,只有DTD作者无法忍受任何不便,这是不可能的.

还要注意,除非儿童序列携带一些信息,否则一些设计当局强烈反对修复序列更好.


小智 9

尝试:

<!ELEMENT parent (child1 | child2 | child3)*>
Run Code Online (Sandbox Code Playgroud)

应该允许零个或多个任何孩子,任何顺序.