Search code examples
javaxmljaxbxjcmaven-jaxb2-plugin

Import JAXB binding snippet into other binding file


For a certain xsd file, I have created a corresponding binding file that does some actions. In my case, annotating ComplexTypes with annotations. Finding the type is done with an XPath expression. The following example demonstrates this:

<jaxb:bindings 
    xmlns:xsd="http://www.w3.org/2001/XMLSchema" 
    xmlns:jaxb="http://java.sun.com/xml/ns/jaxb"
    xmlns:xjc= "http://java.sun.com/xml/ns/jaxb/xjc" 
    version="2.1" 
    xmlns:annox="http://annox.dev.java.net" jaxb:extensionBindingPrefixes="annox">

    <jaxb:bindings schemaLocation="FirstSchema.xsd" node="/xsd:schema">

        <jaxb:bindings node="//xsd:complexType//xsd:element[contains(@type, 'SomeType')]" required="false">
            <annox:annotate target="field">@com.example.Type(type = "SomeType")</annox:annotate>
        </jaxb:bindings>

        //About 100 lines of bindings
    </jaxb:bindings>

</jaxb:bindings>

There are more bindings defined than just the single I've shown, but my problem is that the bindings are now executed on the FirstSchema.xsd. I have a lot of other xsd files that require the exact same bindings. If I have over 10 more xsd files, I'd have to copy-paste these bindings every time for every schema.

Is it possible to "extract" the bindings and re-use them for every other xsd file like an import? It's kind of related to this comment/question. The advised solution there is using jaxb:schemaBindings/jaxb:package, but if I understand correctly the following snippet just generates the classes into another package and doesn't really solve the problem?

<jaxb:schemaBindings>
    <jaxb:package name="com.example.package"/>
</jaxb:schemaBindings>

Solution

  • You'll be surprized, but old-school XML inclusion works with XJB files.

    binding.xjb:

    <!DOCTYPE jaxb:bindings [
    <!ENTITY gh24type SYSTEM "gh24type.xml">
    ]>
    <jaxb:bindings
        xmlns:jaxb="http://java.sun.com/xml/ns/jaxb"
        xmlns:xsd="http://www.w3.org/2001/XMLSchema"
        xmlns:annox="http://annox.dev.java.net"
        jaxb:extensionBindingPrefixes="annox"
    
        jaxb:version="2.1">
    
        <jaxb:bindings schemaLocation="schema.xsd" node="/xsd:schema">
            <!-- ... -->
            &gh24type;
        </jaxb:bindings>
    </jaxb:bindings>
    

    gh24type.xml:

    <jaxb:bindings node="xsd:complexType[@name='gh24Type']">
        <annox:annotate>@javax.annotation.Generated({"jaxb2-annotate-plugin"})</annox:annotate>
    </jaxb:bindings>
    

    So basically nothing spectacular, just entity-based XML inclusion. If you have exactly the same fragments, just include your entity several times for each of the schemas in question.

    Alternatives would be writing a special plugin to simplify customization. Which might be a good idea anyway.