views:

53

answers:

2

I met a problem when JAXB unmarshalling xml data.

JAXB throws exception when unmarshalling empty value for int, double or date attribute from xml. For example, it throws java.lang.NumberFormatException when it unmarshals the following xml data.

<sku displayName="iphone" price=""/>

The following is my schema.

<?xml version="1.0" encoding="UTF-8"?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"&gt;
<xs:element name="sku" type="SkuType" maxOccurs="unbounded"/>
<xs:complexType name="SkuType">
<xs:attribute name="displayName" type="xs:string" use="required"/>  
<xs:attribute name="price" type="xs:double" use="required"/>
<xs:attribute name="startDate" type="xs:dateTime" use="optional"/>
<xs:attribute name="minimumOrderQty" type="xs:integer" use="optional"/>
</xs:complexType>
</xs:schema>

Sorry for the messy xml. I can't type "left angle" sign in input. Can anyone help me out?

Thanks a lot.

+2  A: 

The error is being thrown because the empty string "" is not a valid double. If price is required then it must be assigned a valid double value.

Instead of price="" you should either set a value like price="0" or make the attribute optional.

Valid price attribute:

<sku displayName="iphone" price="0"/>

Price attribute as an optional attribute:

<xs:attribute name="price" type="xs:double" use="optional"/>
Dunderklumpen
Dunderklumpen, Thanks for your help. I am not allowed to change the xml data. However, even I set the attribute to optional, I still have the same exception. startDate="" or minimumOrderQty="" will also get the exception. Do you know anything I can do to force JAXB accept empty value as valid? Thanks
David
You cannot parse XML when it violates the XSD. You need to change the XSD definition to make the price attribute a String. The JAXB will parse it as a string attribute. The String to number conversion can then take place after the JAXB parse, when valid numbers can be converted from String to number.
Dunderklumpen
to be specific, you should change the attribute price to be type="xs:string"
Dunderklumpen
I see. Setting default value won't work either. I think your solution--change to string type is the only way. Thanks a lot. I realy appreiate your help.
David
Unfortunately its not an issue with JAXB its a basic XML issue. JAXB is fairly strict about the XML needing to be valid (and rightly so too). If the XSD has been provided by the people providing the XML, they should be informed that the value "" is not legal for number and date types.
Dunderklumpen
A: 

You may restrict price attribute type to be union of empty string and integer values. While this will still map price attribute to String validation of XML Schema will check that only empty string and integers are valid as values for price attribute. Here's schema example:

<xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema"&gt;
   <xsd:element name="product" type="product"/>

   <xsd:complexType name="product">
      <xsd:attribute name="name" type="xsd:string"/>
      <xsd:attribute name="price" type="emptyInt"/>
   </xsd:complexType>

   <xsd:simpleType name="emptyInt">
      <xsd:union>
         <xsd:simpleType>
            <xsd:restriction base="xsd:integer"/>
         </xsd:simpleType>
         <xsd:simpleType>
            <xsd:restriction base="xsd:token">
               <xsd:enumeration value=""/>
            </xsd:restriction>
         </xsd:simpleType>
      </xsd:union>
   </xsd:simpleType>
</xsd:schema>
syntetic