I'm trying to create a validation scenario where I want to choose at least one non-repeating element from a list.
Somewhere along the lines of:
<xs:choice minOccurs="1" maxOccurs="7">
<xs:element name="Sunday"/>
<xs:element name="Monday"/>
<xs:element name="Tuesday"/>
<xs:element name="Wednesday"/>
<xs:element name="Thursday"/>
<xs:element name="Friday"/>
<xs:element name="Saturday"/>
</xs:choice>
However the above solution allows duplicate elements to appear in a list, which I don't want.
Example of a valid XML:
<Monday/>
<Tuesday/>
<Friday/>
Example of an invalid XML:
<Monday/>
<Monday/>
Can this be achieved with an XSD without having to hardcode all the possible sequences? If so how?
When "minOccurs=1" is contained within an XML Schema Definition (XSD), it means that the first occurrence of the element is required. The element does not need to contain any data, it just needs to be present.
XSD elements can be of type simpleType , complexType , or anyType . An element of type simpleType contains only text. It cannot have attributes and elements. An element of type complexType can contain text, elements, and attributes.
The complexType element defines a complex type. A complex type element is an XML element that contains other elements and/or attributes.
The nillable attribute can be defined on an xsd:element within an XML schema. It specifies that the xsi:nil attribute is valid for the element. If an XML schema has defined the nillable attribute as true, it is mapped as a required attribute and is included in the document, however, its values are nullified.
I do not believe your constraint can be expressed in XSD 1.0 "without having to hardcode all the possible sequences" (but see C. M. Sperberg-McQueen's clever solution that cuts down the combinatorics considerably) . The values of elements could be forced to be unique using xsd:unique
, but subset of XPath used by xsd:unique
does not include name()
, which could otherwise help make a uniqueness statement about the names of the elements.
Your constrain can be expressed in XSD 1.1 using xs:assert
:
<?xml version="1.0" encoding="UTF-8"?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"
xmlns:vc="http://www.w3.org/2007/XMLSchema-versioning" elementFormDefault="qualified"
vc:minVersion="1.1">
<xs:element name="Days">
<xs:complexType>
<xs:choice minOccurs="1" maxOccurs="7">
<xs:element name="Sunday"/>
<xs:element name="Monday"/>
<xs:element name="Tuesday"/>
<xs:element name="Wednesday"/>
<xs:element name="Thursday"/>
<xs:element name="Friday"/>
<xs:element name="Saturday"/>
</xs:choice>
<xs:assert test="count(*[name() = following-sibling::*/name()]) = 0"/>
</xs:complexType>
</xs:element>
</xs:schema>
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With