Code generation failed when using xs:alternative
Problem reported by Kenji Yamazaki - 2/10/2020 at 12:28 PM
Resolved
Hi
I tried to use 'xs:alternative', but it failed.
The attached image is a screenshot of the online version, but using the trial version of Liquid Studio 2020 gives the same result. 

Liquid Support Replied
Employee Post
Thanks for your feedback, we are able to replicate this issue and are investigating.
Liquid Support Replied
Employee Post Marked As Resolution
Firstly there is a bug in the code relating to simpleTypes and alternatives, which has now been fixed and will be in the next release (its a test path that was never run as it's not really practical to use).

However... the problem is more with the schema

You have a schema
<xs:schema elementFormDefault="qualified" version="1.1" xmlns:xs="http://www.w3.org/2001/XMLSchema">
  <xs:element name="a">
    <xs:alternative test="@kind='INT'" type="xs:int" />
    <xs:alternative test="@kind='STRING'" type="xs:string" />
  </xs:element>
</xs:schema>    
Which I assume you want to use to produce XML that looks like this

<a kind="INT">12</a>
so when kind is INT the value 12 validates as an xs:int

Ignoring the xs:alternative for a moment, the schema defintion for 'a' does not permit the attribute 'kind', so the the xs:alternative options will never be used.

If you change and add the 'kind' attribute, then you run into other problems
<xs:schema elementFormDefault="qualified" version="1.1" xmlns:xs="http://www.w3.org/2001/XMLSchema">
  <xs:element name="a">
    <xs:complexType>
      <xs:attribute name="kind" type="xs:string" />
    </xs:complexType>
    <xs:alternative test="@kind='INT'" type="xs:int" />
    <xs:alternative test="@kind='STRING'" type="xs:string" />
  </xs:element>
</xs:schema>    
Now the schema is invalid, let me explain. 
The main rule for xs:alternative is that the base type of 'a' must be the base type of the alternative types (in this case xs:int and xs:string).

When you have
<xs:element name="a"/>
it effectively says the base type of 'a' is xs:anySimpleType. xs:anySimpleType is the base type for xs:int and xs:string, so everything is valid (but, you can't add the 'kind' attribute).


When you change the defintion of 'a' to 
<xs:element name="a">
  <xs:complexType>
    <xs:attribute name="kind" type="xs:string" />
  </xs:complexType>
</xs:element>    
the base type of 'a' is now a xs:complexType, which is not a base type of xs:int or xs:string.

Basically there is no base type that is common to xs:int, xs:string and a xs:complexType (required to add the attribute 'kind'), so you can't do what your trying to do this way.

You could achieve the same thing with xs:asserts and xs:unions, but the LXO generator does not validate the asserts.

<?xml version="1.0" encoding="utf-8" ?> 
<!--Created with Liquid Studio 2019 (https://www.liquid-technologies.com)-->
<xs:schema elementFormDefault="qualified" xmlns:xs="http://www.w3.org/2001/XMLSchema">
  <xs:element name="a">
    <xs:complexType>
      <xs:simpleContent>
        <xs:extension base="StringOrIntType">
          <xs:attribute name="kind" type="xs:string" />
          <xs:assert test="(@kind='INT' and . castable as xs:int) or (@kind='STRING')" /> 
        </xs:extension>
      </xs:simpleContent>
    </xs:complexType>
  </xs:element>
  <xs:simpleType name="StringOrIntType">
    <xs:union memberTypes="xs:int xs:string" />
  </xs:simpleType>
</xs:schema>
    

UPDATE: 03/2020

Having looked at this again, it is possible to do what you want by re-structuring the XSD.

<?xml version="1.0" encoding="utf-8" ?>
<!--Created with Liquid Studio 2020 (https://www.liquid-technologies.com)-->
<xs:schema elementFormDefault="qualified" version="1.1" xmlns:xs="http://www.w3.org/2001/XMLSchema">
    <xs:element name="a">
        <xs:alternative test="@kind='INT'" type="IntValueType" />
        <xs:alternative test="@kind='STRING'" type="StringValueType" />
    </xs:element>
    <xs:complexType name="StringValueType">
        <xs:simpleContent>
            <xs:extension base="xs:string">
                <xs:attribute name="kind" fixed="STRING" type="xs:string" use="required" />
            </xs:extension>
        </xs:simpleContent>
    </xs:complexType>
    <xs:complexType name="IntValueType">
        <xs:simpleContent>
            <xs:extension base="xs:int">
                <xs:attribute name="kind" fixed="INT" type="xs:string" use="required" />
            </xs:extension>
        </xs:simpleContent>
    </xs:complexType>
</xs:schema>
The key point to note is; that because element 'a' has no type attribute its base type is effectivley xs:anyType, which is the base type for all types, so the rules for the xs:alternative type are satisified.

Reply to Thread