[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