1

I have several XML schemas over which I do not have control and I'd like to apply certain customizations when generating the Java classes via XJC.

Some customizations should apply to all .xsd files, but I'm not sure how to achieve this.

At the moment I have this .xjb file:

<jxb:bindings version="2.1" 
  xmlns:jxb="http://java.sun.com/xml/ns/jaxb" 
  xmlns:xs="http://www.w3.org/2001/XMLSchema"
  xmlns:inheritance="http://jaxb2-commons.dev.java.net/basic/inheritance"
  jxb:extensionBindingPrefixes="inheritance">

    <jxb:bindings schemaLocation="../schemas/A.xsd">
         <jxb:schemaBindings>
            <jxb:package name="my.foo.a" />
        </jxb:schemaBindings> 

        <jxb:bindings node="//xs:complexType[@name='A']">
            <jxb:class name="A" />
            <inheritance:implements>my.foo.interfaces.IA</inheritance:implements>           
         </jxb:bindings>

         <jxb:bindings node="//xs:complexType[@name='Device']">
            <jxb:class name="Device" />
            <inheritance:implements>my.foo.interfaces.IDevice</inheritance:implements>          
         </jxb:bindings>             
    </jxb:bindings>

    <jxb:bindings schemaLocation="../schemas/B.xsd">        
        <jxb:schemaBindings>
            <jxb:package name="my.foo.b" />
        </jxb:schemaBindings>

        <jxb:bindings node="//xs:complexType[@name='B']">
            <jxb:class name="B" />
            <inheritance:implements>my.foo.interfaces.IB</inheritance:implements>       
         </jxb:bindings>

        <jxb:bindings node="//xs:complexType[@name='Device']">
            <jxb:class name="Device" />
            <inheritance:implements>my.foo.interfaces.IDevice</inheritance:implements>          
         </jxb:bindings>             
    </jxb:bindings>      
</jxb:bindings>

And this Ant task:

<taskdef name="xjc" classname="org.jvnet.jaxb2_commons.xjc.XJC2Task">
    <classpath>
        <fileset dir="../../dependencies/lib" >
            <include name="activation-*.jar"/>
            <include name="jaxb-api-*.jar"/>
            <include name="jaxb-impl-*.jar"/>
            <include name="jsr173_api-*.jar"/>
            <include name="stax-api-*.jar"/>

            <include name="jaxb2-basics-jaxb-xjc-*.jar"/>
            <include name="jaxb-xjc-*.jar"/>
            <include name="jaxb2-basics-ant-*.jar"/>
        </fileset>
    </classpath>
</taskdef>

<xjc destdir="../src" extension="true" header="false" binding="bindings.xjb">
    <arg line="-Xinheritance"/>

    <schema dir="../schemas">
        <include name="*.xsd"/>
        <exclude name="Foo.xsd"/>
    </schema>

    <!-- Plugins -->
    <classpath>
        <fileset dir="../../dependencies/lib">
            <!-- JAXB2 Basics library -->
            <include name="jaxb2-basics-*.jar"/>
            <!-- JAXB2 Basics library dependencies -->
            <include name="jaxb2-basics-runtime-*.jar"/>
            <include name="jaxb2-basics-tools-*.jar"/>
            <include name="javaparser-*.jar"/>
            <include name="commons-beanutils-*.jar"/>
            <include name="commons-lang-*.jar"/>
            <include name="commons-logging-*.jar"/>
        </fileset>
    </classpath>
</xjc>

Finally what I would like to do is to somehow specify the common blocks (of which I have more than one), ie:

<jxb:bindings node="//xs:complexType[@name='Device']">
    <jxb:class name="Device" />
    <inheritance:implements>my.foo.interfaces.IDevice</inheritance:implements>          
</jxb:bindings> 

For all of my .xsd files.

Hypothetically, something like this:

<jxb:bindings version="2.1" 
  xmlns:jxb="http://java.sun.com/xml/ns/jaxb" 
  xmlns:xs="http://www.w3.org/2001/XMLSchema"
  xmlns:inheritance="http://jaxb2-commons.dev.java.net/basic/inheritance"
  jxb:extensionBindingPrefixes="inheritance">

    <jxb:bindings schemaLocation="../schemas/*.xsd">
        <jxb:bindings node="//xs:complexType[@name='Device']">
            <jxb:class name="Device" />
            <inheritance:implements>my.foo.interfaces.IDevice</inheritance:implements>          
        </jxb:bindings>  
    </jxb:bindings>

    <jxb:bindings schemaLocation="../schemas/A.xsd">
        <jxb:schemaBindings>
            <jxb:package name="my.foo.a" />
        </jxb:schemaBindings> 

        <jxb:bindings node="//xs:complexType[@name='A']">
            <jxb:class name="A" />
            <inheritance:implements>my.foo.interfaces.IA</inheritance:implements>           
        </jxb:bindings>           
    </jxb:bindings>

    <jxb:bindings schemaLocation="../schemas/B.xsd">        
        <jxb:schemaBindings>
            <jxb:package name="my.foo.b" />
        </jxb:schemaBindings>

        <jxb:bindings node="//xs:complexType[@name='B']">
            <jxb:class name="B" />
            <inheritance:implements>my.foo.interfaces.IB</inheritance:implements>       
        </jxb:bindings>       
    </jxb:bindings>      
</jxb:bindings>

How can I accomplish this?

Paul
  • 16,535
  • 5
  • 46
  • 70

1 Answers1

3

So, for (the most part) using this answer here: https://stackoverflow.com/a/18592030/770023

I have managed to get the schema working, for reference all you need to do is set schemaLocation="*" (in order to read all the schemas, of course) and mark the binding elements with multiple="true" and required="false" since some schemas may contain those elements (one or more times), some may not contain them at all.

<jxb:bindings version="2.1" 
  xmlns:jxb="http://java.sun.com/xml/ns/jaxb" 
  xmlns:xs="http://www.w3.org/2001/XMLSchema"
  xmlns:inheritance="http://jaxb2-commons.dev.java.net/basic/inheritance"
  jxb:extensionBindingPrefixes="inheritance">

    <jxb:bindings schemaLocation="*">
        <jxb:bindings node="//xs:complexType[@name='Device']" multiple="true" required="false">
            <inheritance:implements>my.foo.interfaces.IDevice</inheritance:implements>          
        </jxb:bindings>  
    </jxb:bindings>
    <!-- rest of the bindings (per schema ones) go here -->
</jxb:bindings>

Please note that for some (unknown to me) reason I had to remove the class bindings (eg. <jxb:class name="Device" />) for the file to be accepted by XJC.

It mostly works, what I haven't been able to get working is the inheritance:extends customization, which doesn't want to run under the same conditions as the implements one...

Paul
  • 16,535
  • 5
  • 46
  • 70