2

具有以下 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想强制在. 我尝试将上述内容更改为以下内容(长话短说,将 替换为并将相应更改为):AppleBananaCherryDurianElderberryFigFruitssequencechoiceminOccurs1

<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,但它允许CherryDurianEldeberryFig分别在 中出现多达四次Fruits,而我的意图是它们中的每一个分别应该最多允许存在Fruits一次(这就是我尝试maxOccurs="4"在(嵌套)choice元素中使用的原因)。

4

1 回答 1

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="0" 和 minOccurs="1" 之间的区别更加突出。)

这比设计师坚持不下订单时的相应问题要简单得多。但它可能仍然感觉有点笨重。

您可以使用嵌套选择设计,并在应用程序级别指定唯一重要的是给定水果的存在,而不是存在的次数,因此<Fruits><Cherry/><Cherry/><Fig/></Fruits>在语义上与<Fruits><Cherry/><Fig/></Fruits>. 这还不算太糟糕,如果实际上它们是空元素,但如果它们有很长的复杂内容(特别是如果两个不同的 Cherry 实例可能给出不同的,即冲突的信息),它可能看起来太危险或太混乱了。

您可以添加一个 Schematron 验证层并添加一个断言,即 Fruits 至少有一个孩子(如果您保留最初的草图)或 Fruits 最多有一个任何种类的孩子(如果您使用嵌套选择方法) .

于 2014-05-08T23:43:42.447 回答