Reputation: 5432
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;
Upvotes: 3
Views: 6669
Reputation: 148977
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.
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.
Upvotes: 2
Reputation: 4347
The element name in XmlElement annotation on getValue is missing. JAXB default behavior is that getValue means 'value' element, not 'Value'. Add the annotation @XmlElement(name="Value")
Fix it as in your other code
@XmlRootElement(name = "Year")
public static Year {
...
@XmlElement(name="Value")
public int getValue() {
return Value;
}
...
}
If you also marshal I recommend to add @XmlAccessorType(XmlAccessType.NONE) to the classes to prevent adding both 'value' and 'Value' elements.
See full working code at package 'wicketstuff/enteam/wicket/examples14/mixed' on https://repo.twinstone.org/projects/WISTF/repos/wicket-examples-1.4/browse/
Also a test that log into console your XML and parse it back is provided in 'YearOutputTest'
Upvotes: 1
Reputation: 163
</Payload>
instead of
<Payload>
in the last but one line@XmlElement int Value;
Upvotes: 1