Search code examples
javajaxbmoxy

Compiling XML schema to Java with key/keyref identity constraints


Lets say I have the following XML schema:

<xs:schema 
    xmlns="http://www.example.com/data"
    xmlns:data="http://www.example.com/data"
    targetNamespace="http://www.example.com/data"
    elementFormDefault="qualified"
    xmlns:xs="http://www.w3.org/2001/XMLSchema">
    <xs:element name="data">
        <xs:complexType>
            <xs:all>
                <xs:element name="countries">
                    <xs:complexType>
                        <xs:choice minOccurs="0" maxOccurs="unbounded">
                            <xs:element name="country" type="country"/>
                        </xs:choice>
                    </xs:complexType>
                </xs:element>
                <xs:element name="types">
                    <xs:complexType>
                        <xs:choice minOccurs="0" maxOccurs="unbounded">
                            <xs:element name="type" type="type"/>
                        </xs:choice>
                    </xs:complexType>
                </xs:element>
                <xs:element name="products">
                    <xs:complexType>
                        <xs:choice minOccurs="0" maxOccurs="unbounded">
                            <xs:element name="product" type="product"/>
                        </xs:choice>
                    </xs:complexType>
                </xs:element>               
            </xs:all>
        </xs:complexType>  
        <xs:key name="countryNameKey">
            <xs:selector xpath=".//data:country"/>
            <xs:field xpath="@name"/>
        </xs:key>
        <xs:key name="typeNameKey">
            <xs:selector xpath=".//data:type"/>
            <xs:field xpath="@name"/>
        </xs:key>
        <xs:keyref name="countryNameRef" refer="data:countryNameKey">
            <xs:selector xpath=".//data:product"/>
            <xs:field xpath="@country"/>
        </xs:keyref>
        <xs:keyref name="typeNameRef" refer="data:typeNameKey">
            <xs:selector xpath=".//data:product"/>
            <xs:field xpath="@type"/>
        </xs:keyref>  
        <xs:unique name="uniqueProducts">
            <xs:selector xpath=".//data:product"/>
            <xs:field xpath="@country"/>
            <xs:field xpath="@type"/>
        </xs:unique>      
    </xs:element>          
    <xs:complexType name="country">            
        <xs:attribute name="name" type="xs:string" use="required"/>        
    </xs:complexType>
    <xs:complexType name="type">            
        <xs:attribute name="name" type="xs:string" use="required"/>
    </xs:complexType>
    <xs:complexType name="product">            
        <xs:attribute name="country" type="xs:string" use="required"/>
        <xs:attribute name="type" type="xs:string" use="required"/>        
    </xs:complexType>    
</xs:schema>

Excuse the contrived example.

As you can see it is tabular data. I define some countries, then I define some types of product. I then define individual products as a type from a country, cheese from France for example.

The important thing to note here is that I use key and keyref to cross-reference all products back to the original country/type.

So, my question is:

Is it possible to compile this schema into java classes that can be unmarshalled using Eclipse Moxy with the cross-references intact?

I know that the JAXB 2.0 spec does not support key/keyref. I also know that Moxy Does.1

Further I know that Moxy doesn't have a Maven plugin and, in any case, uses XJC generated classes and simply adds in a jaxb.properties file to specify the JAXB provider to use.2

So I suspect the answer to my question is "no, you have to craft the classes yourself", but I thought I'd check before I abandoned hope.

To clarify, My product element currently compiles (using maven-jaxb2-plugin) to

@XmlAccessorType(XmlAccessType.FIELD)
@XmlType(name = "product")
public class Product implements Cloneable, CopyTo, Equals, HashCode, ToString {

    @XmlAttribute(name = "country", required = true)
    protected String country;
    @XmlAttribute(name = "type", required = true)
    protected String type;
//getters and setters
}

It, references the Strings rather than the Country and Type objects.


Solution

  • Currently EclipseLink JAXB (MOXy) only extends the XJC tool to add a jaxb.properties file that indicates that MOXy is the JAXB (JSR-222) provider. I have entered the following enhancement (currently unscheduled) to track this request: