DTD 所需元素排序

发布于 2024-09-05 02:46:19 字数 688 浏览 8 评论 0原文

我想要以 dtd 中定义的任何顺序列出所需元素,但不知道如何做到这一点。

例如,我有以下定义:

<!ELEMENT parent (child1, child2, child3)>

此 dtd 声明将成功验证以下 xml 片段:

<parent>
   <child1></child1>
   <child2></child2>
   <child3></child3>
</parent>

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

<parent>
   <child2></child2>
   <child1></child1>
   <child3></child3>
</parent>

可能的解决方案之一是声明

<!ELEMENT parent (child1 | child2 | child3)>

但在这种情况下,通过验证可能会丢失其中一个子项将会成功。

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

I want to have list of required elements in any order defined in dtd, but have no idea how I could do this.

For example, I have following definition:

<!ELEMENT parent (child1, child2, child3)>

This dtd declaration will successfully validate following piece of xml:

<parent>
   <child1></child1>
   <child2></child2>
   <child3></child3>
</parent>

But in following case xml will not pass validation:

<parent>
   <child2></child2>
   <child1></child1>
   <child3></child3>
</parent>

One of the possible solution is to declare

<!ELEMENT parent (child1 | child2 | child3)>

But in this case one of the childs might be missing though validation will be successful.

I need correct dtd element declaration for the case when list of required elements can be present in any order.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

阪姬 2024-09-12 02:46:19

ChrisF 说你不能这样做是错误的(但值得称赞的是检查规范!); DevNull [现在称为 Daniel Haley] 说可以的,这是正确的。

然而,有一个复杂的问题:DevNull 为 parent 提供的内容模型违反了 XML 的确定性规则。非正式地说,这些规则表示解析器必须知道文档中的每个元素与内容模型中的哪个标记相匹配,而无需先行查找。如果解析器在 parent 元素中看到 child1,则无需前瞻就无法知道它是否刚刚匹配 child1 的第一次出现或第二次出现> 在 DevNull 的内容模型中。这是一个错误(但事实上,这是一个处理器没有义务报告的错误——这个错误意味着“所有的赌注都被取消了,处理器可能会在这里做任何事情,包括没有注意到任何错误”)。

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

<!ELEMENT parent ( 
                   (child1, ( (child2,child3)
                            | (child3,child2)))
                 | (child2, ( (child1,child3)
                            | (child3,child1)))
                 | (child3, ( (child1,child2)
                            | (child2,child1)))
                 ) >

这比其他模式语言中的该模型的声明以及对于三个以上的元素而言不太方便手工操作很容易出错并且极其乏味。但使用 DTD 声明您想要的内容模型并非不可能。或者也许我应该说,只有那些无法忍受任何不便的 DTD 作者才是不可能的。

另请注意,除非子项的序列携带一些信息,否则一些设计权威强烈认为最好修复一个序列。

ChrisF is wrong to say you can't do this (but kudos for checking the spec!); DevNull [now known as Daniel Haley] is right to say you can.

There is, however, one complication: the content model given by DevNull for parent violates the determinism rules of XML. Informally, these rules say the parser must know, without lookahead, which token in the content model each element in the document matches. If in a parent element the parser sees a child1, it can't know without lookahead whether it has just matched the first or second occurrence of child1 in DevNull's content model. This is an error (but as it happens it's an error that processors are not obligated to report -- it's an error that means "all bets are off, the processor may do anything here, including fail to notice anything is wrong").

A content model for parent that obeys the determinism rules can be formed by factoring out common prefixes, thus:

<!ELEMENT parent ( 
                   (child1, ( (child2,child3)
                            | (child3,child2)))
                 | (child2, ( (child1,child3)
                            | (child3,child1)))
                 | (child3, ( (child1,child2)
                            | (child2,child1)))
                 ) >

This is less convenient than declarations for this model can be in other schema languages, and for more than three elements it's error prone and extremely tedious to do by hand. But it's not impossible to declare the content model you want with DTDs. Or perhaps I should say it's impossible only for DTD authors who are incapable of putting up with any inconvenience.

Note also that unless the sequence of children carries some information, some design authorities argue strongly that it's better to fix a sequence.

死开点丶别碍眼 2024-09-12 02:46:19

尝试:

<!ELEMENT parent (child1 | child2 | child3)*>

应该以任何顺序允许零个或多个任何子项。

Try:

<!ELEMENT parent (child1 | child2 | child3)*>

Should allow zero or more of any child, in any order.

你的背包 2024-09-12 02:46:19

阅读规范看起来你不能。

当子项以逗号分隔的顺序声明时,子项必须以相同的顺序出现在文档中。完整申报时,孩子也必须申报,孩子也可以生孩子。

我认为这是因为您声明的是序列(或有序列表,如果您愿意)而不是集合(或无序列表)。

Reading the spec is would appear you can't.

When children are declared in a sequence separated by commas, the children must appear in the same sequence in the document. In a full declaration, the children must also be declared, and the children can also have children.

I think it's because you are declaring a sequence (or ordered list if you like) rather than a collection (or unordered list).

只有一腔孤勇 2024-09-12 02:46:19

当您只需要每个子元素之一时,这是很棘手的。这是我能想到的唯一方法,但它不是很漂亮。不过它是有效的...

<!ELEMENT parent ( 
                 (child1,child2,child3)|
                 (child1,child3,child2)|
                 (child2,child1,child3)|
                 (child2,child3,child1)|
                 (child3,child1,child2)|
                 (child3,child2,child1)
                )>

基本上我指定了一个 child1、child2 和 child3 元素的每一种可能的组合。

这是一个示例。 child1child2child3 可以采用任意顺序,但它们都必须恰好出现一次。

<!DOCTYPE parent [
<!ELEMENT parent ( 
                 (child1,child2,child3)|
                 (child1,child3,child2)|
                 (child2,child1,child3)|
                 (child2,child3,child1)|
                 (child3,child1,child2)|
                 (child3,child2,child1)
                )>
<!ELEMENT child1 (#PCDATA)>
<!ELEMENT child2 (#PCDATA)>
<!ELEMENT child3 (#PCDATA)>
]>
<parent>
  <child2></child2>
  <child1></child1>
  <child3></child3>
</parent>

This is tricky when you need exactly one of each child elements. This is the only way I can think of and it's not very pretty. It works though...

<!ELEMENT parent ( 
                 (child1,child2,child3)|
                 (child1,child3,child2)|
                 (child2,child1,child3)|
                 (child2,child3,child1)|
                 (child3,child1,child2)|
                 (child3,child2,child1)
                )>

Basically I'm specifying every possible combination of exactly one child1, child2, and child3 elements.

Here's an example instance. child1, child2, and child3 can be in any order, but they each must occur exactly one time.

<!DOCTYPE parent [
<!ELEMENT parent ( 
                 (child1,child2,child3)|
                 (child1,child3,child2)|
                 (child2,child1,child3)|
                 (child2,child3,child1)|
                 (child3,child1,child2)|
                 (child3,child2,child1)
                )>
<!ELEMENT child1 (#PCDATA)>
<!ELEMENT child2 (#PCDATA)>
<!ELEMENT child3 (#PCDATA)>
]>
<parent>
  <child2></child2>
  <child1></child1>
  <child3></child3>
</parent>
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文