简体   繁体   中英

XML & JAXB: pass attribute into value

I have a large amount of objects generated through JAXB ( maven-jaxb2-plugin ) and annotate them with the jaxb2-annotate-plugin . These classes may define a RelationType and I'd like to annotate them with the corresponding @RelationType annotation. I use an XPath expression to find the name attribute in the XSD and annotate the class, passing its specific type into the annotation. An example of this is the following:

<jaxb:bindings node="//xsd:complexType[@name='SomeRelationType']">
    <annox:annotate target="class">@com.example.RelationType(type = "SomeRelationType")</annox:annotate>
</jaxb:bindings>

which maps on the following XSD snippet:

<xsd:complexType name="SomeRelationType">
    <xsd:complexContent>
        <xsd:extension base="RelationType">
            <xsd:sequence>
                <xsd:element name="someValue" type="SomeValue"/>
                <xsd:element name="otherValue" type="OtherValue"/>                     
            </xsd:sequence>
        </xsd:extension>
    </xsd:complexContent>
</xsd:complexType>

I find the ComplexType with the SomeRelationType name and annotate the class with a @RelationType annotation, which has the SomeRelationType as its type parameter. It would generate the following class:

@RelationType(type = "SomeRelationType")
public class SomeRelationType extends RelationType implements Serializable {
    private final static long serialVersionUID = 1L;
    protected SomeValue someValue;
    protected OtherValue otherValue;    
}

This works fine if it were just a few domain objects. But I have a large amount and defining every annotation manually is not only tedious but also bad in terms of change and expansion.

To generify it, I can rewrite the XPath expression to the following:

<jaxb:bindings node="//xsd:complexType[substring(@name, string-length(@name) - string-length('RelationType') + 1)]" multiple="true">
    <annox:annotate target="class">@com.example.RelationType(type = "SomeRelationType")</annox:annotate>
</jaxb:bindings>

The problem: The type parameter of my annotation is still defined as "SomeRelationType" . It would be great if I could use the same @name as defined in the XPath expression. Then all the classes whose name ends with "RelationType" also automatically gets its @RelationType annotation with the correct type parameter.

It doesn't work as simple as doing the following of course, but it shows what I'd like to achieve:

<jaxb:bindings node="//xsd:complexType[substring(@name, string-length(@name) - string-length('RelationType') + 1)]" multiple="true">
    <annox:annotate target="class">@com.example.RelationType(type = @name)</annox:annotate>
</jaxb:bindings>

Is such a thing even possible or is this impossible in XML/JAXB?

But I have a large amount and defining every annotation manually is not only tedious but also bad in terms of change and expansion.

For me, @com.example.RelationType(type = "SomeRelationType") looks like a trivial metainformation which could be derived via reflection without any annotations. So check if there's a way to do "convention over configuration" thing.

The jaxb2-annotate-plugin does not and will not support parameterization, it would be too narrow and too complex to implement. Disclaimer I'm the author of the jaxb2-annotate-plugin .

I see two options:

  • Pre-generate bindings in your build. XML Schema is XML so writing XSLT to produce bindings files should not be too complicated.
  • Write an own XJC plugin to add annotations as you want them.
  • Bribe me to add parameterization to the jaxb2-annotate-plugin .

Right, just two options.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM