Reputation: 26
The XML I'm structuring can contain any number of "user" elements, and I want to ensure that an attribute called "isDefault" is set to true on exactly one of those users.
For example, something like this would be valid:
<users>
<user isDefault="false"/>
<user isDefault="true"/>
<user isDefault="false"/>
</users>
However, this:
<users>
<user isDefault="true"/>
<user isDefault="true"/>
<user isDefault="false"/>
</users>
And this:
<users>
<user isDefault="false"/>
<user isDefault="false"/>
<user isDefault="false"/>
</users>
Would be invalid. Can I achieve this using an XSD or do I need to validate it programmatically?
Upvotes: 1
Views: 68
Reputation: 25034
One simple way to solve this problem is to re-think the XML and specify that the default user is listed first, and the user listed first is the default user. Then a change to the default user involves moving that user to the top of the list, instead of changing two isDefault
values, and you are guaranteed without any further effort that there is always exactly one user
element which is first.
Upvotes: 1
Reputation: 23637
If the isDefault
attribute has to always be present, you can't achieve this with XSD 1.0 alone.
With XSD 1.1 you could use an <xs:assert>
:
<xs:element name="users">
<xs:complexType>
<xs:sequence>
<xs:element ref="user" maxOccurs="unbounded"/>
</xs:sequence>
<xs:assert test="count(user[@isDefault='true']) = 1"/>
</xs:complexType>
</xs:element>
Upvotes: 0