Java – classes generated using JAXB are used for elements that require integers with patterns
An element in my XML schema is defined as follows:
<xs:complexType name="MyNumberCodeType"> <xs:sequence> <xs:element name="Code" type="NumberCodeValueType" maxOccurs="unbounded" /> </xs:sequence> </xs:complexType>
Where numbercodevaluetype is:
<xs:simpleType name="NumberCodeValueType"> <xs:restriction base="xs:int"> <xs:pattern value="[0-7]{7}"/> </xs:restriction> </xs:simpleType>
In other words, my number can start from 0 I can't modify this mode I am using JAXB to generate my java classes Unfortunately, the accessor of the code element takes a list of integers as a parameter, which means that all leading zeros are stripped (because I can see that there is no way to keep leading zeros in Java when using integer types)!
Is there any way to solve this problem?
Thanks for your help!
Solution
You can do the following:
Numberformatter for
You can do this by writing your own formatting:
package forum7182533; public class NumberFormatter { public static String printInt(Integer value) { String result = String.valueOf(value); for(int x=0,length = 7 - result.length(); x<length; x++) { result = "0" + result; } return result; } public static Integer parseInt(String value) { return Integer.valueOf(value); } }
XMLSchema(format.xsd)
Then when you want to generate your classes from your XML Schema:
<?xml version="1.0" encoding="UTF-8"?> <xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"> <xs:element name="root"> <xs:complexType> <xs:sequence> <xs:element name="number" type="NumberCodeValueType" /> </xs:sequence> </xs:complexType> </xs:element> <xs:simpleType name="NumberCodeValueType"> <xs:restriction base="xs:int"> <xs:pattern value="[0-7]{7}" /> </xs:restriction> </xs:simpleType> </xs:schema>
bindings. xml
You will use the JAXB binding file to reference your formatter:
<jxb:bindings xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:jxb="http://java.sun.com/xml/ns/jaxb" version="2.1"> <jxb:bindings schemaLocation="format.xsd"> <!--jxb:bindings node="//xs:simpleType[@name='NumberCodeValueType']" --> <jxb:bindings node="//xs:element[@name='number']"> <jxb:property> <jxb:baseType> <jxb:javaType name="java.lang.Integer" parseMethod="forum7182533.NumberFormatter.parseInt" printMethod="forum7182533.NumberFormatter.printInt" /> </jxb:baseType> </jxb:property> </jxb:bindings> </jxb:bindings> </jxb:bindings>
Xjc telephone
The binding file is referenced in the xjc call as:
xjc -d out -p forum7182533 -b bindings.xml format.xsd
Adapter 1
This will result in creating an xmladapter that utilizes your formatter:
package forum7182533; import javax.xml.bind.annotation.adapters.XmlAdapter; public class Adapter1 extends XmlAdapter<String,Integer> { public Integer unmarshal(String value) { return (forum7182533.NumberFormatter.parseInt(value)); } public String marshal(Integer value) { return (forum7182533.NumberFormatter.printInt(value)); } }
root
The xmladapter will be referenced from your domain object using the @ xmljavatypeadapter annotation:
package forum7182533; import javax.xml.bind.annotation.XmlAccessType; import javax.xml.bind.annotation.XmlAccessorType; import javax.xml.bind.annotation.XmlElement; import javax.xml.bind.annotation.XmlRootElement; import javax.xml.bind.annotation.XmlType; import javax.xml.bind.annotation.adapters.XmlJavaTypeAdapter; @XmlAccessorType(XmlAccessType.FIELD) @XmlType(name = "",propOrder = { "number" }) @XmlRootElement(name = "root") public class Root { @XmlElement(required = true,type = String.class) @XmlJavaTypeAdapter(Adapter1 .class) protected Integer number; public Integer getNumber() { return number; } public void setNumber(Integer value) { this.number = value; } }
demonstration
Now, if you run the following demo code:
package forum7182533; import javax.xml.bind.JAXBContext; import javax.xml.bind.Marshaller; public class Demo { public static void main(String[] args) throws Exception { JAXBContext jc = JAXBContext.newInstance(Root.class); Root root = new Root(); root.setNumber(4); Marshaller marshaller = jc.createMarshaller(); marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT,true); marshaller.marshal(root,System.out); } }
yield
You will get the desired output:
<?xml version="1.0" encoding="UTF-8" standalone="yes"?> <root> <number>0000004</number> </root>