Question

I am using JAXB for marshalling and unmarshalling objects. I have a Class MyBean with List of String as a field and annotated with @XmlAttribute.

@XmlRootElement
public class MyBean {
    public MyBean() {
        super();

    }
    private List<String> actualValue;

    @XmlAttribute
    public List<String> getActualValue() {
        if (actualValue == null) {
            actualValue = new ArrayList<String>();
        }
        return actualValue;
    }
    public void setActualValue(List<String> values) {
        this.actualValue = values;
    }
}

Following is the Test class for marshaling and un-marshelling MyBean.

public class Test {

public static void main(String[] args) {

    try {
        // create object ....
        MyBean myBean = new MyBean();
        List<String> values = new ArrayList<String>();
        values.add("Sanjv Singh Baghel");
        myBean.setActualValue(values);



        // Marsheling
        File file = new File("D://Temp//hello2.xml");
        JAXBContext jaxbContext2 = JAXBContext.newInstance(MyBean.class);
        Marshaller jaxbMarshaller2 = jaxbContext2.createMarshaller();
        jaxbMarshaller2.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true);
        jaxbMarshaller2.setProperty(Marshaller.JAXB_ENCODING, "UTF-8");
        jaxbMarshaller2.marshal(myBean, file);

        // Un-Marsheling
        JAXBContext jaxbContext = JAXBContext.newInstance(MyBean.class);
        Unmarshaller jaxbUnmarshaller = jaxbContext.createUnmarshaller();

        // printing actual value
        MyBean myBean2 = (MyBean) jaxbUnmarshaller.unmarshal(file);
        List<String> actualValue = myBean2.getActualValue();
        System.out.println(actualValue);
    } catch (JAXBException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    }

    }

}

Output :

Before actualValue : ["sanjv singh baghel"]
After  actualValue : ["sanjv, singh, baghel"]

The strange thing, I am facing here is that original actualValue only has one String with Spaces and after un-marshalling, that single String is converted to list of String (divided by Space).

I want to know why this is happening / what is wrong with it.

For, I find two possible solutions for that:

  • Replace @XmlAttribute with @XmlElement
  • List<String> actualValue; & String needs to be mapped to a schema simple type
Was it helpful?

Solution

XML Schema has the concept of a list of data types.

<xs:attribute name="actualValue">
     <xs:simpleValue>
         <xs:list itemType="xs:string"/>
     <xs:simpleValue>
</xs:attribute>

This is represented in XML as space separated values.

<foo actualValue="one two three"/>

This is what you have asked JAXB to do by placing the @XmlAttribute annotation on a property of type List<String>. See "Example 3" in the javadoc for @XmlAttribute.

If you replace @XmlAttribute with @XmlElement you will ge the following representation:

<foo>
    <actualValue>one</actualValue>
    <actualValue>two</actualValue>
    <actualValue>three</actualValue>
</foo>
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top