为什么我不能将 xs:all 放在 xs:sequence 中?

Why can't I put an xs:all inside a xs:sequence?

我对 XML Schema 还是有点陌生​​,我正在尝试在 Relax NG Compact 中做一些看起来像这样的事情:

test = element test{
element A {text},
element B {text},
(element C {text}? &
element D {text}?)
}

表示在test元素中包含A,然后是B,然后是任意顺序C和D,这两个都是可选的.

按照我的看法,我应该可以简单地说

<xs:element name="test">
    <xs:complexType>
        <xs:sequence>
            <xs:element name="A"/>
            <xs:element name="B"/>
            <xs:all>
                <xs:element name="C"/>
                <xs:element name="D"/>
            </xs:all> 
        </xs:sequence>
    </xs:complexType>
</xs:element>

但它不允许我将 <xs:all> 放在 <xs:sequence> 中。说

s4s-elt-must-match.1: The content of 'sequence' must match (annotation?, (element | group | choice | sequence | any)*). A problem was found starting at: all.

所以我尝试从 <xs:sequence> 中取出 <xs:all>,如下所示:

<xs:element name="test">
        <xs:complexType>
            <xs:sequence>
                <xs:element name="A" />
                <xs:element name="B"/>
            </xs:sequence>
            <xs:all>
                <xs:element name="C"/>
                <xs:element name="D"/>
            </xs:all> 
        </xs:complexType>
    </xs:element>

但是现在还是不行,说

s4s-elt-invalid-content.1: The content of '#AnonType_test' is invalid. Element 'all' is invalid, misplaced, or occurs too often

所以我很困惑,因为它看起来很简单,但我不知道该怎么做。

你的困惑是可以理解的。问题是XSD设计是不规则的,不规则的设计往往违背我们的预期。

这是一个变通方法,不幸的是,它更冗长,而且对于要排列的大量元素也不切实际:

  <xs:element name="test">
    <xs:complexType>
      <xs:sequence>
        <xs:element name="A"/>
        <xs:element name="B"/>
        <xs:choice minOccurs="0">
          <xs:sequence>
            <xs:element name="C"/>
            <xs:element name="D" minOccurs="0"/>
          </xs:sequence>
          <xs:sequence>
            <xs:element name="D"/>
            <xs:element name="C" minOccurs="0"/>
          </xs:sequence>
        </xs:choice>
      </xs:sequence>
    </xs:complexType>
  </xs:element>

另一种解决方法是强制排序;允许任何顺序在实践中通常并不重要。

在我看来,设计的原因之一是允许混合顺序无关 (all) 和顺序相关 (sequence, choice, .. .) 模型组会增加 XML 模式验证在算法方面的复杂性,并会给实施者带来更多负担。

但不仅如此,在某些情况下,例如涉及可选元素,它还可能导致在将元素与粒子匹配时出现歧义(即模型组内的元素声明),引入非确定性或实现依赖性,这对于互操作性来说是不可取的。

总的来说,此类限制的好处大于成本。大多数 XML Schema 用户使用 sequencechoice 并强制排序(参见 kjhughes 的示例)。

Relax NG(我不熟悉)可能会使用不同的模型来描述元素的内容,并且该模型可能与不同的设计决策兼容。