简体   繁体   中英

Customizing jaxb bindings for primtive

I have several schemas I am generating jaxb bindings for that make liberal use of xs:integer . I wish to have these values bound to long / Long rather than the default BigInteger. Unfortunately I do not have the ability to modify the schemas. Adding a simple declaration to my bindings file causes xs:integer to be bound to Long in all cases, even when it's a required value:

<jaxb:javaType xmlType="xs:integer" name="long" />

How can I get xs:integer to be bound to a primitive when the field is required?

That's pretty simple you just need to have two different bindings in your .jxb file and use correct XPath selector to find the elements which need to be mapped to Integer and another XPath selector which will find elements which are going to be mapped to int .

As you have not posted your .xsd and .xjb files, I will just show on a small example how things are working. Let's assume we have following .xsd file

<xs:schema attributeFormDefault="unqualified" elementFormDefault="qualified"  xmlns:xs="http://www.w3.org/2001/XMLSchema">
    <xs:element name="user">
         <xs:complexType>
             <xs:sequence>
                 <xs:element type="xs:integer" name="age" minOccurs="1"/>
                 <xs:element type="xs:integer" name="balance" minOccurs="0"/>
             </xs:sequence>
         </xs:complexType>
    </xs:element>
</xs:schema>

So from the .xsd we can see that we have a definition of user object which has age property which is required (still we could use use="optional" attribute as well, but that does not matter) and the balance property which is optional.

So lets say we want the age to be mapped to Java int and the balance to Integer .

So we just need a binding file which will find all the nodes which have type attribute equal to xs:integer and minOccurs attribute equal to 1 and apply some custom mapping rule and do the same for all the ones with minOccurs attribute equal to 0.

<jxb:bindings version="2.0" 
    xmlns:jxb="http://java.sun.com/xml/ns/jaxb"
    xmlns:xs="http://www.w3.org/2001/XMLSchema"
    xmlns:xjc="http://java.sun.com/xml/ns/jaxb/xjc"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">

    <jxb:bindings schemaLocation="schema.xsd">
        <!---Find all optional integers and map them to java.lang.Integer -->
        <jxb:bindings node="//xs:element[@minOccurs='0' and @type='xs:integer']" multiple="true">
            <xjc:javaType name="java.lang.Integer" adapter="adapters.IntegerAdapter" />
        </jxb:bindings>

        <!---Find all required integers and map them to primitive int -->
        <jxb:bindings node="//xs:element[@minOccurs='1' and @type='xs:integer']" multiple="true">
            <xjc:javaType name="int" adapter="adapters.IntAdapter" />
        </jxb:bindings>

    </jxb:bindings>
</jxb:bindings>

That's it after running the build (remember to enable vendor customization be adding -extension command line argument) you will have something like this.

@XmlAccessorType(XmlAccessType.FIELD)
@XmlType(name = "", propOrder = {
"age",
"balance"
})
@XmlRootElement(name = "user")
public class User {

    @XmlElement(required = true, type = String.class)
    @XmlJavaTypeAdapter(IntAdapter.class)
    @XmlSchemaType(name = "integer")
    protected int age;
    @XmlElement(type = String.class)
    @XmlJavaTypeAdapter(IntegerAdapter.class)
    @XmlSchemaType(name = "integer")
    protected Integer balance;

    // getters setters will be here
}

Also, note that I'm not adding the sources for adapters.IntegerAdapter and adapters.IntAdapter this part is for you )

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