我仍然对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:'sequence'的内容必须匹配 (注释?,(元素|组|选择|序列|任何)*)。一个问题 被发现从:所有。
所以我尝试从<xs:all>
中取出<xs:sequence>
,如下所示:
<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:'#AnonType_test'的内容无效。元素'all'无效,错位或过于频繁
所以我很困惑,因为它看起来很简单,但我不知道如何做到这一点。
答案 0 :(得分:1)
你的困惑是可以理解的。问题是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>
另一种解决方法是强制执行订购;允许任何订单在实践中通常并不重要。
答案 1 :(得分:0)
在我看来,设计的一个原因是允许混合顺序无关(all
)和依赖顺序(sequence
,choice
,...)模型组会在算法方面增加XML Schema验证的复杂性,并会给实现者带来更多负担。
但更重要的是,在涉及例如可选元素的某些情况下,当将元素与粒子匹配时(即模型组内的元素声明),引入非确定性或实现依赖性,这也会导致模糊性,这是不适合互操作性。
这些限制的好处总体上超过了他们的成本。大多数XML Schema用户使用sequence
和choice
并强制执行订单(请参阅kjhughes的示例)。
放松NG(我不熟悉)可以使用不同的模型来描述元素的内容,这个模型可能与不同的设计决策兼容。