JAXB adds an empty XML attribute as 0

JAXB returns an empty XML attribute as 0, and that's fine, but I have a requirement to keep it as zero. It seems I cannot change the DataConverterImpl class for a custom implementation. What can be done, if at all?

<xs:attribute name="Count" type="Integer0to999" use="optional"> <xs:simpleType name="Integer0to999"> <xs:annotation> <xs:documentation xml:lang="en">Used for Integer values, from 0 to 999 inclusive</xs:documentation> </xs:annotation> <xs:restriction base="xs:integer"> <xs:minInclusive value="0"/> <xs:maxInclusive value="999"/> </xs:restriction> </xs:simpleType> 

After compiling the xjc schema, I got a class with the following:

  @XmlAttribute(name = "Count") protected Integer passengerCount; 

During XML, parse parseInt() is called from DataConverterImpl.class from Sun (Oracle), whose code is below, your neve is going to get null from this code:

  public static int _parseInt(CharSequence s) { int len = s.length(); int sign = 1; int r = 0; for( int i=0; i<len; i++ ) { char ch = s.charAt(i); if(WhiteSpaceProcessor.isWhiteSpace(ch)) { // skip whitespace } else if('0'<=ch && ch<='9') { r = r*10 + (ch-'0'); } else if(ch=='-') { sign = -1; } else if(ch=='+') { ; // noop } else throw new NumberFormatException("Not a number: "+s); } return r*sign; } 
+7
java jaxb
source share
2 answers

You can try writing your own XMLAdaptor, which converts your integer to String (or another object), and then converts it back as you see fit. During unmarshalling, I imagine that a case-insensitive quick check for "null" is all you need.

Start here: http://download.oracle.com/javase/6/docs/api/javax/xml/bind/annotation/adapters/XmlAdapter.html

Attach the adapter to your int field and write the body.

Your converter will start as follows:

 public class MyIntConverter extends XmlAdapter<String,Integer> { @Override public String marshal(Integer value) throws Exception { if ( value.intValue() == 0 ) return null; // Or, "null" depending on what you'd like return value.toString(); } @Override public Integer unmarshal(String storedValue) throws Exception { if ( storedValue.equalsIgnoreCase("null") ) return 0; return Integer.valueOf(storedValue); } } 

Then you can use it:

 @XmlJavaTypeAdapter(MyIntConverter.class) int someNumber; 

The code is not verified, but I think it should solve the problem.

+1
source share

FWIW, I currently find that JAXB disables the empty element to zero (if the whole field), but is null if it is a long field.

Admittedly, this could be some kind of problem with data type converters. Or it could be a bug with the JAXB version with JDK 6.0, and you can use a later version.

+1
source share

All Articles