具有以下XML架构(XSD 1.0):
<xs:element name="Fruits">
<xs:complexType>
<xs:sequence>
<xs:element name="Fruit_id" type="xs:int" minOccurs="1" maxOccurs="1"/>
<xs:choice minOccurs="1" maxOccurs="1">
<xs:element ref="Apple" minOccurs="1" maxOccurs="1"/>
<xs:element ref="Banana" minOccurs="1" maxOccurs="1"/>
<xs:sequence>
<xs:element ref="Cherry" minOccurs="0" maxOccurs="1"/>
<xs:element ref="Durian" minOccurs="0" maxOccurs="1"/>
<xs:element ref="Elderberry" minOccurs="0" maxOccurs="1"/>
<xs:element ref="Fig" minOccurs="0" maxOccurs="1"/>
</xs:sequence>
</xs:choice>
</xs:sequence>
</xs:complexType>
</xs:element>
我遇到的问题是这个架构允许Fruits
只包含Fruit_id
,我想强制执行至少一个水果(即Apple
或Banana
或Cherry
或Durian
或Elderberry
或Fig
)出现在Fruits
中。我尝试将以上内容更改为以下内容(长话短说,将sequence
替换为choice
并将相应的minOccurs
更改为1
):
<xs:element name="Fruits">
<xs:complexType>
<xs:sequence>
<xs:element name="Fruit_id" type="xs:int" minOccurs="1" maxOccurs="1"/>
<xs:choice minOccurs="1" maxOccurs="1">
<xs:element ref="Apple" minOccurs="1" maxOccurs="1"/>
<xs:element ref="Banana" minOccurs="1" maxOccurs="1"/>
<xs:choice minOccurs="1" maxOccurs="4">
<xs:element ref="Cherry" minOccurs="1" maxOccurs="1"/>
<xs:element ref="Durian" minOccurs="1" maxOccurs="1"/>
<xs:element ref="Elderberry" minOccurs="1" maxOccurs="1"/>
<xs:element ref="Fig" minOccurs="1" maxOccurs="1"/>
</xs:choice>
</xs:choice>
</xs:sequence>
</xs:complexType>
</xs:element>
实际上,实施Fruits
中至少有一个上述水果,但它允许Cherry
,Durian
,Eldeberry
和{{1分别在Fig
中出现最多四次,而我的目的是分别允许它们中的每一个分别至少存在Fruits
一次(这就是为什么我在(嵌套的)Fruits
元素中尝试使用maxOccurs="4"
。
答案 0 :(得分:2)
你有几个选择,都有一些缺点。
您可以通过这种方式重写嵌套序列以至少需要一个水果:
<xs:choice>
<xs:sequence>
<xs:element ref="Cherry"/>
<xs:element ref="Durian" minOccurs="0"/>
<xs:element ref="Elderberry" minOccurs="0"/>
<xs:element ref="Fig" minOccurs="0"/>
</xs:sequence>
<xs:sequence>
<xs:element ref="Durian"/>
<xs:element ref="Elderberry" minOccurs="0"/>
<xs:element ref="Fig" minOccurs="0"/>
</xs:sequence>
<xs:sequence>
<xs:element ref="Elderberry"/>
<xs:element ref="Fig" minOccurs="0"/>
</xs:sequence>
<xs:sequence>
<xs:element ref="Fig"/>
</xs:sequence>
</xs:choice>
(我省略了minOccurs和maxOccurs的默认值,以区分minOccurs =&#34; 0&#34;而minOccurs =&#34; 1&#34;更突出。)
当设计师坚持不开具订单时,这比相应的问题简单得多。但它可能仍然感觉有点笨重。
您可以使用嵌套选择设计,并在应用程序级别指定唯一重要的是给定水果的存在,而不是它存在的次数,所以{{1在语义上与<Fruits><Cherry/><Cherry/><Fig/></Fruits>
相同。这不是太糟糕,如果事实上它们是空的元素,但如果它们有很长的复杂内容(特别是如果两个不同的Cherry实例可以提供不同的,即冲突的信息),它可能看起来太危险或令人困惑
您可以添加一个Schematron验证层,并添加一个断言,其中Fruit至少有一个孩子(如果您保留初始草图)或者Fruit最多有一个任何种类的孩子(如果您使用嵌套的 - 选择方法)。