How can I specify the adapter (s) that uses JAXB to marshal / swing data?

Can I specify the adapter that JAXB uses to marshal / unmount 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 circuit:

 <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 circuit using the XJC tool, the string "0x1234" should be decoded using Integer.decode () as an integer with a value of 0x1234 or 4660 in decimal form. The adapter class created reflects this correctly:

 public Integer unmarshal(String value) { return (Integer.decode(value)); } 

However, when I want to bind a value 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 value 0x1234 (4660 in decimal) is โ€œ4660โ€, which does not match my pattern (because it does not have the โ€œ0xโ€ prefix).

How can I tell the adapter that I want the integer 0x1234 to be ordered as the string literal "0x1234"? I would like to be able to do this within a framework so that I can simply generate new Java classes without the need to change the output. Is it possible?

Edit: Based on the accepted answer, here is what I did for this:

I wrote a method in the com.example.Parse class called toHexString ():

 public static String toHexString(int value) { return ("0x" + Integer.toHexString(value)); } 

Then I pointed out my circuit for this printing method:

 <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> 
+8
java xml jaxb
source share
3 answers

try it

 <jaxb:javaType name="int" parseMethod="Integer.decode" printMethod="Integer.toHexString"/> 

I have not tested it, but I remember that I used something very similar.

+5
source share

A very similar problem: "How do I match the string coordinates of java.awt.Point?"

(0) Scheme

 <xsd:simpleType name="Point"> <xsd:restriction base="xsd:string"> <xsd:pattern value="([0-9])+,([0-9])+" /> </xsd:restriction> </xsd:simpleType> <xsd:complexType name="HexAreaBorder"> <xsd:sequence minOccurs="1" maxOccurs="1"> <xsd:element minOccurs="1" maxOccurs="1" name="type" type="xsd:string" /> <xsd:element minOccurs="1" maxOccurs="1" name="name" type="xsd:string" /> <xsd:element name="points" type="Point" minOccurs="1" maxOccurs="unbounded" /> </xsd:sequence> </xsd:complexType> 

(1) Create an adapter class that extends the XmlAdapter.

 package com.kjcode.hexgrid.jaxbadapter; import java.awt.Point; import javax.xml.bind.annotation.adapters.XmlAdapter; public class PointAdapter extends XmlAdapter<String, Point> { @Override public Point unmarshal(String v) throws Exception { String[] coords = v.split(","); return new Point(Integer.parseInt(coords[0]), Integer.parseInt(coords[1])); } @Override public String marshal(Point v) throws Exception { return String.format("%d,%d", vx, vy); } } 

(2) Create a binding file. The key is to add: jaxb: extensionBindingPrefixes = "xjc" xmlns: xjc = "http://java.sun.com/xml/ns/jaxb/xjc"

 <?xml version="1.0" encoding="UTF-8"?> <jaxb:bindings xmlns:jaxb="http://java.sun.com/xml/ns/jaxb" jaxb:extensionBindingPrefixes="xjc" xmlns:xjc="http://java.sun.com/xml/ns/jaxb/xjc" xmlns="hexmap" xmlns:xsd="http://www.w3.org/2001/XMLSchema" jaxb:version="2.1"> <jaxb:bindings schemaLocation="hexmap.xsd"> <jaxb:globalBindings> <xjc:javaType adapter="com.kjcode.hexgrid.jaxbadapter.PointAdapter" name="java.awt.Point" xmlType="Point" /> </jaxb:globalBindings> </jaxb:bindings> </jaxb:bindings> 

(3) Customize pom.xml

 <plugin> <groupId>com.sun.tools.xjc.maven2</groupId> <artifactId>maven-jaxb-plugin</artifactId> <version>1.1.1</version> <executions> <execution> <goals> <goal>generate</goal> </goals> </execution> </executions> <configuration> <generatePackage>com.kjcode.hexmap.api.logic.field.generated</generatePackage> <extension>true</extension> </configuration> </plugin> 

(4) JAXB will generate

 public class HexAreaBorder { @XmlElement(required = true) protected String type; @XmlElement(required = true) protected String name; @XmlElement(required = true, type = String.class) @XmlJavaTypeAdapter(PointAdapter.class) protected List<Point> points = new LinkedList<Point>(); 
+7
source share

You need a custom adapter. Here's a message that deals with a custom boolean result, but can be applied to your scenario as well.

Also here is the API documentation for the JAXB XmlAdapter: http://jaxb.java.net/nonav/2.1/docs/api/javax/xml/bind/annotation/adapters/XmlAdapter.html

Hope this helps!

0
source share

All Articles