Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

JAXB Unmarshal a list of objects

Tags:

java

xml

jaxb

I have the following XML that I am trying to unmarshal:

<ListOfYear>
    <Requests/>
    <Payload>
        <Year>
            <Value>2013</Value>
        </Year>
        <Year>
            <Value>2012</Value>
        </Year>
        <Year>
            <Value>2011</Value>
        </Year>
        <Year>
            <Value>2010</Value>
        </Year>
        <Year>
            <Value>2009</Value>
        </Year>
        <Year>
            <Value>2008</Value>
        </Year>
    </Payload>
</ListOfYear>

My java class looks like this:

@XmlRootElement(name = "ListOfYear")
public class YearOutput {

    @XmlElementWrapper(name = "Payload")
    @XmlElement(name = "Year")
    private ArrayList<Year> Payload;

    public ArrayList<Year> getPayload() {
        return Payload;
    }

    public void setPayload(ArrayList<Year> payload) {
        Payload = payload;
    }
}

Payload should contain a list of year objects:

@XmlRootElement(name = "Year")
@XmlAccessorType(XmlAccessType.FIELD).
public class Year {

    @XmlElement(name = "Value")
    int Value;

    public int getValue() {
        return Value;
    }

    public void setValue(int value) {
        Value = value;
    }
}

I am unmarshaling the XML with the following code:

String r = response.getEntity(String.class);
JAXBContext jaxbContext = JAXBContext.newInstance(YearOutput.class);
Unmarshaller unmarshaller = jaxbContext.createUnmarshaller();

YearOutput output = (YearOutput) unmarshaller.unmarshal(new StringReader(r));

I get an output object back just fine, the payload object is always null. I have tried several different approaches with my XML annotation and have not been able to get anything to work. Any help would be much appreciated.

EDIT I thought the name space was inconsequential so I didn't post that part of the code. But @Blaise Doughan suggested I marshal my model and it appears my namespace may be causing an issue...

Here is the full XML that I need:

<ListOfYear xmlns="http://something.com/">
    <Requests/>
    <Payload>
        <Year>
            <Value>2013</Value>
        </Year>
        <Year>
            <Value>2012</Value>
        </Year>
        <Year>
            <Value>2011</Value>
        </Year>
        <Year>
            <Value>2010</Value>
        </Year>
        <Year>
            <Value>2009</Value>
        </Year>
        <Year>
            <Value>2008</Value>
        </Year>
    </Payload>
</ListOfYear>

Here is my full model:

@XmlRootElement(name = "ListOfYear", namespace = "http://something.com/")
public class YearOutput {

    @XmlElementWrapper(name = "Payload")
    @XmlElement(name = "Year")
    private ArrayList<Year> Payload;

    public ArrayList<Year> getPayload() {
        return Payload;
    }

    public void setPayload(ArrayList<Year> payload) {
        Payload = payload;
    }
}

Now when I marshal my model I am getting:

<?xml version="1.0" encoding="UTF-8"?>
<ns2:ListOfYear xmlns:ns2="https://something.com/">
    <Payload>
        <Year>
            <Value>2008</Value>
        </Year>
    </Payload>
</ns2:ListOfYear>

So what am I doing wrong with my namespace?

EDIT After adding package-info.java everything works perfect!

@XmlSchema(
        namespace = "https://something.com/",
        elementFormDefault = XmlNsForm.QUALIFIED)
package example;

import javax.xml.bind.annotation.XmlNsForm;
import javax.xml.bind.annotation.XmlSchema;
like image 352
ferics2 Avatar asked Nov 26 '25 14:11

ferics2


1 Answers

Your annotations need to go on the property (get or set method) instead of the field. If you wish to have them on the field (instance variable), the you need to annotate your class with @XmlAccessorType(XmlAccessType.FIELD), like you have on your Year class.

  • http://blog.bdoughan.com/2011/06/using-jaxbs-xmlaccessortype-to.html

UPDATE

Instead of specifying the namespace on @XmlRootElement you will need to leverage a package level @XmlSchema annotation (on a class called package-info) to match the namespace qualification.

  • http://blog.bdoughan.com/2010/08/jaxb-namespaces.html
like image 133
bdoughan Avatar answered Nov 28 '25 04:11

bdoughan



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!