这个或那个最有效的架构,或者这个和那个

时间:2010-01-14 14:47:13

标签: xml schema xsd

我正在尝试编写一个XML模式,允许以下列方式表达XML:

宠物可以包含猫和狗元素:

<root>
  <pets>
    <cat />
    <dog />
  </pets>
</root>

宠物只能包含猫或狗元素

<root>
  <pets>
    <cat />
  </pets>
</root>
-----------
<root>
  <pets>
    <dog />
  </pets>
</root>

如果宠物没有子元素,那么它应该不存在:

<root>
</root>

我为满足这些条件而提出的最佳架构是:

<xs:element name="pets">
  <xs:complexType>
    <xs:choice>
      <xs:sequence>
        <xs:element name="cat"/>
        <xs:element name="dog" minOccurs="0"/>
      </xs:sequence>
      <xs:sequence>
        <xs:element name="dog"/>
      </xs:sequence>
    </xs:choice>
  </xs:complexType>
</xs:element>

对于这样一个简单的概念,我似乎总是喜欢过多的模式。是否有更简单的方法来编写此架构?谢谢!

2 个答案:

答案 0 :(得分:3)

我认为这是使用xs:group元素的理想情况:如果你将它包裹在你的元素周围并使其成为可选的(同时使元素的内容成为必需元素),你将获得所需的效果。

<xs:group name="pets_group">
  <xs:element name="pets" minOccurs="0" maxOccurs="1">
    <xs:complexType>
      <xs:choice>
        <xs:sequence>
          <xs:element name="cat"/>
          <xs:element name="dog" minOccurs="0"/>
        </xs:sequence>
        <xs:sequence>
          <xs:element name="dog"/>
          <xs:element name="cat" minOccurs="0"/>
        </xs:sequence>
      </xs:choice>
    </xs:complexType>
  </xs:element>
</xs:group>

然后使用pets_group组代替使用pets元素:

<xs:element name="root">
  <xs:complexType>
    <xs:group ref="pets_group"/>
  </xs:complexType>
</xs:element>

在猫后跟可选狗和狗跟随可选猫之间做出选择可确保宠物标签中有某物。没有宠物标签是允许您不指定任何宠物的。

或者,您可以将它们一起定义,只需“内联”组引用即可。如果宠物标签只在一个地方使用,这可能就是你想要做的。

答案 1 :(得分:2)

您在问题中提供的解决方案是最常见的解决方案。除了另一个答案中的群体观点,没有更好的方法。就个人而言,我更喜欢你的解决方案。

大标准模式(例如FpML)使用您的模式。