[xsd-users] Specifying Element content for "anyType" Elements

Andre Vautour andre.vautour at caris.com
Wed Jan 14 15:38:30 EST 2015


Hi Boris,
I wasn't sure if I should start a new thread or not. Since this old 
thread was basically the same problem I ran into, I (hopefully 
correctly) decided continuing this old thread was the best way to 
proceed. The thread's archive link is the following:
http://www.codesynthesis.com/pipermail/xsd-users/2008-September/001930.html

It had to do with element references to elements that can be 
substituted, specifically to the naming of those elements in the 
resulting serialized document.

>> i tried to create an PropertyIsEqualTo element which is defined as follows:
>>
>>   <xsd:element name="PropertyIsEqualTo"
>>                  type="ogc:BinaryComparisonOpType"
>>                  substitutionGroup="ogc:comparisonOps"/>
>> [...]
>> As you can see, the generated element is not the desired one but
>> "PropertyIsGreaterThanOrEqualTo".
>>
>> This element is defined like the PropertyIsEqualTo element:
>>
>>   <xsd:element name="PropertyIsGreaterThanOrEqualTo"
>> type="ogc:BinaryComparisonOpType" substitutionGroup="ogc:comparisonOps"/>
>>
>> Because they are both of the same type no other class as
>> ogc:BinaryComparisonOpType is generated.
>
> It looks like this schema is using element names as some sort of
> identifiers even though they are all of the same type. This does
> not work very well with XSD's automatic handling of substitution
> groups since the generated code uses the first element name that
> matches the type. I see two ways how you can resolve this:
>
> 1. You can change the schema to an equivalent one but which assigns
>     different types to different operation elements. This schema will
>     be equivalent to the original in the sense that it will define
>     the same XML vocabulary:
>
>     <xsd:complexType name="IsEqualToType">
>        <xsd:complexContent>
>           <xsd:extension base="ogc:BinaryComparisonOpType"/>
>        </xsd:complexContent>
>     </xsd:complexType>
>    
>     <xsd:element name="PropertyIsEqualTo"
>                  type="ogc:IsEqualToType"
>                  substitutionGroup="ogc:comparisonOps"/>
>
>     <xsd:complexType name="IsGreaterThanOrEqualToType">
>        <xsd:complexContent>
>           <xsd:extension base="ogc:BinaryComparisonOpType"/>
>        </xsd:complexContent>
>     </xsd:complexType>
>
>    <xsd:element name="PropertyIsGreaterThanOrEqualTo"
>                 type="ogc:IsGreaterThanOrEqualToType"
>                 substitutionGroup="ogc:comparisonOps"/>
>
>    And so on for all the elements that substitute comparisonOps and are
>    of the BinaryComparisonOpType type.
I agree that using inheritance instead of substitutions in this schema 
would have been more explicit as well as more simple for code generation 
purposes. Unfortunately, modifying the schema is out of my control. The 
schema is used to generate code not only in C++, but also in other 
languages like using JAXB for Java, so modifying it to accommodate a 
limitation of one of the tools is a hard sell. Keep in mind that you'd 
have to do that suggested modification for all of the comparisonOps, 
spatialOps, temporalOps and logicOps of filter.xsd, for each version of 
the standard:
http://schemas.opengis.net/filter/1.0.0/filter.xsd
http://schemas.opengis.net/filter/1.1.0/filter.xsd
http://schemas.opengis.net/filter/2.0/filter.xsd

Also, looking at other OGC and ISO schema files I expect to want to 
generate in the future, I see lots of element references with possible 
substitutions, so I expect several of them would also need to be modified.

> 2. The second method is quite a bit more involved but does not require
>     any schema modifications. With this method you will need to customize
>     all the types that contain the comparisonOps element (e.g., FilterType).
>     Your customization will need to do two things:
>
>     a) Add a mechanism for specifying which element name should be used.
>        This can be a modifier function that passes element name as a
>        string.
>
>     b) Customize the serialization operator to change the name of the
>        DOM element.
This solution, like you said, is quite a bit involved. In addition, 
having to set the child's name on the parent really doesn't make sense 
to me. I expect it would also cause confusion to people using the 
generated classes as they would not know that they need to set the name. 
It also only seems to address serialization where I also need to parse 
such documents and the child element name is important to correctly 
interpret the document. I'm certainly not ruling out customizations as a 
potential solution, but I would rather one that is more hidden from code 
that uses the generated code.

Did you consider supporting/doing something similar to what JAXB does in 
this situation? As described in http://stackoverflow.com/a/3659338, in 
cases where such a substitution group is used, the generated code takes 
in a JAXBElement (equivalent to element_type) instead of the type object 
directly. Calling code can then get/set the name on that intermediate 
object: http://docs.oracle.com/javaee/5/api/javax/xml/bind/JAXBElement.html

Kind Regards,
André




More information about the xsd-users mailing list