Reputation: 15284
I have two tags in XSD:
<xsd:element name="tag1" minOccurs="0">
<xsd:element name="tag2" minOccurs="0">
They are both optional and can be omitted. However I want to add a restriction that if tag2 is given, tag1 should also be given (as tag2 is dependent on tag1). How to achieve this by just XSD?
Edit:
There are mandatory tags between them. Thus a sequence will not work. e.g.
<xsd:element name="tag1" minOccurs="0">
<xsd:element name="tag3" minOccurs="1">
<xsd:element name="tag4" minOccurs="1">
<xsd:element name="tag2" minOccurs="0">
Upvotes: 1
Views: 176
Reputation: 6016
Here are some solutions:
This is a long solution as it repeats parts of the model but it works if you really need mandatory tags between the optional tags and tags are not inside an 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>
Note that you can avoid repeating tags on the model if you use an xs:group
to group your complusory central tags.
If there were not mandatory tags between them you could simply wrap them in a sequence with minOccurs=0
. So if the sequence appears then both tags are present, and if the sequence doesn't appears none of the tags are present:
<xsd:sequence minOccurs="0">
<xsd:element name="tag1"/>
<xsd:element name="tag2"/>
</xsd:sequence>
Note that this won't work inside an xs:all
but you can use it inside a choice or even inside another sequence if you want.
If your processor is using XSD 1.1 you can use xs:assert to ensure that either all of the optional tags are present or either none of them is present:
<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>
Note that this is the only one of the solution presenteds that would also work with xs:all
.
Upvotes: 2