Is there a way to specify the Adapter which JAXB uses for marshaling/unmarshaling objects in my XML schema?
For example, if I want to parse the following as an integer:
<SpecialValue>0x1234</SpecialValue>
I can use the following in my schema:
<xs:simpleType name="HexInt">
<xs:annotation>
<xs:appinfo>
<jaxb:javaType name="int" parseMethod="Integer.decode" />
</xs:appinfo>
</xs:annotation>
<xs:restriction base="xs:string">
<xs:pattern value="0x[0-9a-fA-F]+" />
</xs:restriction>
</xs:simpleType>
<xs:element name="SpecialValue" type="HexInt" />
When I run the schema through the XJC tool, the String "0x1234" should be decoded using Integer.decode() as the Integer with value 0x1234, or 4660 in decimal. The Adapter class that is generated reflects this properly:
public Integer unmarshal(String value) {
return (Integer.decode(value));
}
However, when I want to marshal the value back to an XML element (which is a String literal), the Adapter class does the following:
public String marshal(Integer value) {
if (value == null) {
return null;
}
return value.toString();
}
In this case, the String value of the integer 0x1234 (4660 in decimal) is "4660", which does not adhere to my schema (because it has no "0x" prefix).
How can I tell the Adapter that I want the integer 0x1234 to be marshalled as the "0x1234" String literal? I would be like to be able to do this within the schema so that I can just generate new Java classes without having to modify the output. Is this possible?
Edit: Based on the accepted answer, here is what I did to get this working:
I wrote a method in a class com.example.Parse called toHexString():
public static String toHexString(int value)
{
return ("0x" + Integer.toHexString(value));
}
Then I pointed my schema to that method for printing:
<xs:simpleType name="HexInt">
<xs:annotation>
<xs:appinfo>
<jaxb:javaType name="int" parseMethod="Integer.decode" printMethod="com.example.Parse.toHexString" />
</xs:appinfo>
</xs:annotation>
<xs:restriction base="xs:string">
<xs:pattern value="0x[0-9a-fA-F]+" />
</xs:restriction>
</xs:simpleType>
Try this
I haven't tested it though but I remember using something very similar.
Very similar problem: "How to map String coordinates to java.awt.Point ?"
(0) Schema
(1) Create adapter class that extends XmlAdapter.
(2) Create bindings file. The key is to add: jaxb:extensionBindingPrefixes="xjc" xmlns:xjc="http://java.sun.com/xml/ns/jaxb/xjc"
(3) Configure pom.xml
(4) JAXB will generate
You want a custom Adapter. Here's a post that deals with a custom boolean result, but could be applied to your scenario as well.
In addition, here's the API documentation for JAXB's XmlAdapter: http://jaxb.java.net/nonav/2.1/docs/api/javax/xml/bind/annotation/adapters/XmlAdapter.html
Hope this helps!