如何使两个可选标签中的一个依赖于另一个?
How to make one of two optional tag dependent on the other?
我在 XSD 中有两个标签:
<xsd:element name="tag1" minOccurs="0">
<xsd:element name="tag2" minOccurs="0">
它们都是可选的,可以省略。但是我想添加一个限制,如果给出了 tag2,也应该给出 tag1(因为 tag2 依赖于 tag1)。如何通过 XSD?
实现这一目标
编辑:
它们之间有强制标签。因此序列将不起作用。例如
<xsd:element name="tag1" minOccurs="0">
<xsd:element name="tag3" minOccurs="1">
<xsd:element name="tag4" minOccurs="1">
<xsd:element name="tag2" minOccurs="0">
以下是一些解决方案:
使用一个选项
这是一个很长的解决方案,因为它重复了模型的某些部分,但如果您确实需要可选标签之间的强制性标签并且标签不在 xs:all
:
<xsd:choice>
<!-- Choice option 1: optional tags present -->
<xsd:sequence>
<xsd:element name="optionalTag1"/>
<xsd:element name="complulsoryTag1"/>
<xsd:element name="complulsoryTag2"/>
<xsd:element name="optionalTag2"/>
</xsd:sequence>
<!-- Choice option 2: optional tags not present -->
<xsd:sequence>
<xsd:element name="complulsoryTag1"/>
<xsd:element name="complulsoryTag2"/>
</xsd:sequence>
</xsd:choice>
请注意,如果您使用 xs:group
对强制性中央标签进行分组,则可以避免在模型上重复标签。
按可选顺序包装标签
如果它们之间没有强制性标签,您可以简单地将它们按 minOccurs=0
的顺序包装起来。因此,如果序列出现,则两个标签都存在,如果序列不出现,none 个标签存在:
<xsd:sequence minOccurs="0">
<xsd:element name="tag1"/>
<xsd:element name="tag2"/>
</xsd:sequence>
请注意,这在 xs:all
中不起作用,但您可以在选择中使用它,如果需要,甚至可以在另一个序列中使用它。
使用XSD 1.1断言
如果您的处理器使用的是 XSD 1.1,您可以使用 xs:assert 来确保所有可选标签都存在,或者其中 none 个存在:
<xsd:complexType>
<xsd:sequence>
<xsd:element name="optionalTag1" minOccurs="0"/>
<xsd:element name="complulsoryTag1"/>
<xsd:element name="complulsoryTag2"/>
<xsd:element name="optionalTag2" minOccurs="0"/>
</xsd:sequence>
<!-- Both optional tags are present or none of them are present -->
<xsd:assert test="boolean(optionalTag1) = boolean(optionalTag2)"/>
</xsd:complexType>
请注意,这是唯一一种也适用于 xs:all
的解决方案。
我在 XSD 中有两个标签:
<xsd:element name="tag1" minOccurs="0">
<xsd:element name="tag2" minOccurs="0">
它们都是可选的,可以省略。但是我想添加一个限制,如果给出了 tag2,也应该给出 tag1(因为 tag2 依赖于 tag1)。如何通过 XSD?
实现这一目标编辑:
它们之间有强制标签。因此序列将不起作用。例如
<xsd:element name="tag1" minOccurs="0">
<xsd:element name="tag3" minOccurs="1">
<xsd:element name="tag4" minOccurs="1">
<xsd:element name="tag2" minOccurs="0">
以下是一些解决方案:
使用一个选项
这是一个很长的解决方案,因为它重复了模型的某些部分,但如果您确实需要可选标签之间的强制性标签并且标签不在 xs:all
:
<xsd:choice>
<!-- Choice option 1: optional tags present -->
<xsd:sequence>
<xsd:element name="optionalTag1"/>
<xsd:element name="complulsoryTag1"/>
<xsd:element name="complulsoryTag2"/>
<xsd:element name="optionalTag2"/>
</xsd:sequence>
<!-- Choice option 2: optional tags not present -->
<xsd:sequence>
<xsd:element name="complulsoryTag1"/>
<xsd:element name="complulsoryTag2"/>
</xsd:sequence>
</xsd:choice>
请注意,如果您使用 xs:group
对强制性中央标签进行分组,则可以避免在模型上重复标签。
按可选顺序包装标签
如果它们之间没有强制性标签,您可以简单地将它们按 minOccurs=0
的顺序包装起来。因此,如果序列出现,则两个标签都存在,如果序列不出现,none 个标签存在:
<xsd:sequence minOccurs="0">
<xsd:element name="tag1"/>
<xsd:element name="tag2"/>
</xsd:sequence>
请注意,这在 xs:all
中不起作用,但您可以在选择中使用它,如果需要,甚至可以在另一个序列中使用它。
使用XSD 1.1断言
如果您的处理器使用的是 XSD 1.1,您可以使用 xs:assert 来确保所有可选标签都存在,或者其中 none 个存在:
<xsd:complexType>
<xsd:sequence>
<xsd:element name="optionalTag1" minOccurs="0"/>
<xsd:element name="complulsoryTag1"/>
<xsd:element name="complulsoryTag2"/>
<xsd:element name="optionalTag2" minOccurs="0"/>
</xsd:sequence>
<!-- Both optional tags are present or none of them are present -->
<xsd:assert test="boolean(optionalTag1) = boolean(optionalTag2)"/>
</xsd:complexType>
请注意,这是唯一一种也适用于 xs:all
的解决方案。