Search code examples
xmlxpathjaxbxjc

JAXB bindings - address content of an xs:string extension with xpath


I want to configure xjc to annotate a certain attribute in a generated Java class using the jaxb2-basics-annotate plugin but I am struggling to address the particular XML element with XPath.

Here is an extract of the xsd (which btw, cannot be changed by myself):

<xs:complexType name="ExpressionType">
        <xs:simpleContent>
            <xs:extension base="xs:string">
                <xs:attribute name="id" type="xs:string" use="required"/>
            </xs:extension>
        </xs:simpleContent>
</xs:complexType>

The corresponding xjc-generated Java class looks like this:

....
public class ExpressionType
{

    @XmlValue
    protected String value;
    @XmlAttribute(name = "id", required = true)
    protected String id;

    ...

in the bindings.xjb file I'd like to configure that the Java attribute value gets annotated by annotation XmlJavaTypeAdapter, so something like this:

<jxb:bindings node="//xs:complexType[@name='ExpressionType']/<???>" multiple="true">
    <annox:annotate target="field">@javax.xml.bind.annotation.adapters.XmlJavaTypeAdapter(MyOwnCdataAdapter.class)</annox:annotate>
</jxb:bindings>

The three ??? refer to my question ;-) : How to address the inner content which is mapped to Java attribute value in XPath?

For the id attribute I succeeded using

//xs:complexType[@name='ExpressionType']/xs:simpleContent/xs:extension/xs:attribute[@name='id']

but for my demands, I don't see how to express this in xpath, also reflecting that the type is an extension of xs:string.


Solution

  • Please see this issue for the solution.

    I just copy-paste the solution here to avoid the "link-only" downvotes.


    This appeared to be more complex than I thought. I did not manage to attach customizations to the simple content-derived property with standard XJC means. So I wrote the customizations plugin which reads customizations from files, associated with classes or fields. For instance, org\jvnet\jaxb2_commons\tests\issues\Gh24Type.value.xml customizes the value property of the org.jvnet.jaxb2_commons.tests.issues.Gh24Type class.

    So how it works:

    • Include jaxb2-basics
    • Enable -Xcustomizations plugin and point -Xcustomizations-directory=<dir> to whatever directory you want to load customizations files from. For instance, ${basedir}/src/main/resources.
    • Create a file named after the class and/or property you want to customize. For instance for the value property of the org.jvnet.jaxb2_commons.tests.issues.Gh24Type class you'll have the src/main/resources/org/jvnet/jaxb2_commons/tests/issues/Gh24Type.value.xml file.
    • Put your customizations into this file. Must be valid XML, for instance:

      @javax.xml.bind.annotation.adapters.XmlJavaTypeAdapter(MyOwnCdataAdapter.class)

    See this project, especially Gh24Type for example.

    The new feature has been released with version 1.0.3 of jaxb2-basics.

    Hope this helps.


    Disclaimer: I'm the author of the jaxb2-annotate-plugin as well as the solution described above.