Code generation failed when using xs:alternative
Problem reported by Kenji Yamazaki - February 10 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. 

2 Replies

Reply to Thread
0
Liquid Support Replied
Employee Post
Thanks for your feedback, we are able to replicate this issue and are investigating.
1
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