Sunday, March 1, 2020

XML Schema 1.1 <alternative> use cases with <choice> and <attribute>

While using XML Schema (XSD) 1.1, many times when we use XSD 1.1 <assert> we could find a solution using XSD 1.1 <alternative> as well for the same use cases (and vice versa as well). This is usually the case, when the XML child content model of an element, is dependent on the values of attributes of an element on which the attributes appear. This is evident for the first example, of my previous blog post. Given the same XML input examples, as in the first example of my previous blog post, the following XML Schema 1.1 example using <alternative> is also a possible solution,

<?xml version="1.0"?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema">

    <xs:element name="X">
       <xs:alternative test="xs:boolean(@isB) eq true()">
          <xs:complexType>
             <xs:sequence>
               <xs:element name="b" type="xs:string"/>
            </xs:sequence>
             <xs:attribute name="isB" type="xs:boolean" use="required"/>
          </xs:complexType>
       </xs:alternative>
       <xs:alternative>
          <xs:complexType>
             <xs:choice>
               <xs:element name="a" type="xs:string"/>            
               <xs:element name="c" type="xs:string"/>
            </xs:choice>
             <xs:attribute name="isB" type="xs:boolean" use="required"/>
          </xs:complexType>
       </xs:alternative>
    </xs:element>

</xs:schema>

Then the question arises, for these same use cases should we use XSD 1.1 <assert> or an <alternative>? Below are the pros and cons for this, according to me:
1) An XSD 1.1 solution, using <assert> has less lines of code than the one using <alternative>, which many would consider as a benefit.
2) I personally, prefer an XPath expression '@isB = true()' (within 'if (@isB = true()) then b else not(b)') of an <assert> over 'xs:boolean(@isB) eq true()' in an <alternative>. With these examples, for the example involving <alternative> an attribute node 'isB' has a type annotation of xs:untypedAtomic that requires an explicit cast with xs:boolean(..). I tend to prefer, the XPath expressions that don't use explicit casts (since, such XPath expressions look more schema aware).
3) One of the benefits, I see with the solution using an XSD 1.1 <alternative> over <assert>, is better error diagnostics in case of XML validation errors.

No comments: