I've been imagining that, what could be useful use cases of XML Schema (XSD) 1.1 <assert> construct.
According to the XSD 1.1 structures specification, "assertion components constrain the existence and values of related XML elements and attributes".
One of useful use cases possible for XSD 1.1 <assert> is, to constrain the standard behavior of XSD 1.0 / 1.1 <choice> construct. I'll attempt to write something about this, here on this blog post.
Below is an XSD schema example using the <choice> construct, that is correct for both 1.0 and 1.1 versions of XSD language:
<?xml version="1.0"?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema">
<xs:element name="X">
<xs:complexType>
<xs:choice>
<xs:element name="a" type="xs:string"/>
<xs:element name="b" type="xs:string"/>
<xs:element name="c" type="xs:string"/>
</xs:choice>
</xs:complexType>
</xs:element>
</xs:schema>
The above schema document, ensures that following XML instance documents would be valid:
<X>
<a>some string</a>
</X>
,
<X>
<b>some string</b>
</X>
,
<X>
<c>some string</c>
</X>
(essentially showing that, element 'X' can have only one of the elements 'a', 'b' or 'c' as a child element)
Lets see how the above XSD example, can be made a little different using XSD elements <attribute> and <assert>. Below is such a modified XSD document,
<?xml version="1.0"?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema">
<xs:element name="X">
<xs:complexType>
<xs:choice>
<xs:element name="a" type="xs:string"/>
<xs:element name="b" type="xs:string"/>
<xs:element name="c" type="xs:string"/>
</xs:choice>
<xs:attribute name="isB" type="xs:boolean" use="required"/>
<xs:assert test="if (@isB = true()) then b else not(b)"/>
</xs:complexType>
</xs:element>
</xs:schema>
The complete meaning of above XSD document is following,
1) The <choice> with three <element> declarations below it, essentially are the same constraints as the earlier XSD document has shown.
2) This schema additionally specifies, a mandatory boolean typed attribute named 'isB'.
3) The <assert> specifies that, if value of attribute 'isB' is true then element 'b' must be present as a child of element 'X'. If value of attribute 'isB' is false, then element 'X' cannot have element 'b' as its child but one of elements 'a' or 'c' would be a valid child of element 'X'.
The following XML instance documents would be valid according to above mentioned XSD document:
<X isB="1">
<b>some string</b>
</X>
,
<X isB="0">
<a>some string</a>
</X>
,
<X isB="0">
<c>some string</c>
</X>
And, the following XML instance documents would be invalid according to the same XSD document:
<X isB="0">
<b>some string</b>
</X>
,
<X isB="1">
<a>some string</a>
</X>
,
<X isB="0">
<d>some string</d>
</X>
Now lets consider another XSD example, where the schema document specifies a choice between three or more sequences. Below is mentioned such a schema document:
<?xml version="1.0"?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema">
<xs:element name="X">
<xs:complexType>
<xs:choice>
<xs:sequence>
<xs:element name="a" type="xs:string"/>
<xs:element name="b" type="xs:string"/>
</xs:sequence>
<xs:sequence>
<xs:element name="p" type="xs:string"/>
<xs:element name="q" type="xs:string"/>
</xs:sequence>
<xs:sequence>
<xs:element name="x" type="xs:string"/>
<xs:element name="y" type="xs:string"/>
</xs:sequence>
</xs:choice>
<xs:attribute name="isSeqTwo" type="xs:boolean" use="required"/>
<xs:assert test="if (@isSeqTwo = true()) then p else not(p)"/>
</xs:complexType>
</xs:element>
</xs:schema>
The complete meaning of above XSD document is following,
1) A <choice> is specified between three <sequence> elements. Therefore, element 'X' can have one of following sequences as its child: {a, b}, {p, q} or {x, y}.
2) This schema additionally specifies, a mandatory boolean typed attribute named 'isSeqTwo'.
3) The <assert> specifies that, if value of attribute 'isSeqTwo' is true then sequence {p, q} must be present as a child of element 'X'. If value of attribute 'isSeqTwo' is false, then element 'X' cannot have sequence {p, q} as its child but one of sequences {a, b} or {x, y} would be a valid child of element 'X'.
The following XML instance documents would be valid according to above mentioned XSD document:
<X isSeqTwo="1">
<p>string1</p>
<q>string2</q>
</X>
,
<X isSeqTwo="0">
<a>string1</a>
<b>string2</b>
</X>
,
<X isSeqTwo="0">
<x>string1</x>
<y>string2</y>
</X>
And, the following XML instance documents would be invalid according to the same XSD document:
<X isSeqTwo="0">
<p>string1</p>
<q>string2</q>
</X>
,
<X isSeqTwo="1">
<a>string1</a>
<b>string2</b>
</X>
,
<X isSeqTwo="0">
<i>string1</i>
<j>string2</j>
</X>
All the above examples, and any other XSD 1.0/1.1 constructs may be used with any standards compliant XSD validator.
That's about all I wanted to say, about this topic.
No comments:
Post a Comment