Reputation: 1279
I have an xml document which looks like this
<root>
<subElement>
<a>an instance</a>
<b>another instance</b>
<problemElement>
<option>1st instance</option>
<option>2nd instance</option>
<option>3rd instance</option>
</problemElement>
</subElement>
<subElement>
<a></a>
<b></b>
<problemElement>
<option>instance</option>
</problemElement>
</subElement>
</root>
and my jaxb classes look like this;
@XmlRootElement(name = "root")
@XmlType(name = "Root")
public class Root{
@XmlElement(name = "subElement", required = true)
private final List<SubElement> subElementList = new ArrayList<SubElement>();
public List<SubElement> getSubElementList() {
return subElementList;
}
}
@XmlType(name = "SubElement", propOrder = {"a", "b", "problemElement"})
public abstract class SubElement{
@XmlElement(required = true)
private String a;
@XmlElement(required = true)
private String b;
@XmlElement(name = "problemElement", required = true)
private List<ProblemElement> problemElement= new ArrayList<ProblemElement>();
public String getA() {
return a;
}
public String getB() {
return b;
}
public List<ProblemElement> getProblemElement() {
return problemElement;
}
}
@XmlType(name = "ProblemElement" )
public class ProblemElement {
@XmlElement(required = true)
private String option;
public String getOption() {
return option;
}
}
Everything works fine except the problemElement. The list only returns the last option node value in the xml, in this case "3rd instance". What am I doing wrong?
Upvotes: 2
Views: 1454
Reputation: 149047
SHORT ANSWER
For you use case I would leverage the @XmlElementWrapper
annotation on the problemElement
property:
@XmlElementWrapper(name="problemElement")
@XmlElement(name="option")
private List<ProblemElement> problemElement = new ArrayList<ProblemElement>();
The I would use the @XmlValue
property on the option
property:
@XmlValue
private String option;
LONG ANSWER
Below is a completely mapped example.
Root
package forum10531285;
import java.util.*;
import javax.xml.bind.annotation.*;
@XmlRootElement(name = "root")
@XmlType(name = "Root")
@XmlAccessorType(XmlAccessType.FIELD)
public class Root {
@XmlElement(name = "subElement", required = true)
private final List<SubElement> subElementList = new ArrayList<SubElement>();
}
SubElement
package forum10531285;
import java.util.*;
import javax.xml.bind.annotation.*;
@XmlType(name = "SubElement", propOrder = { "a", "b", "problemElement" })
@XmlAccessorType(XmlAccessType.FIELD)
public class SubElement {
@XmlElement(required = true)
private String a;
@XmlElement(required = true)
private String b;
@XmlElementWrapper(name="problemElement")
@XmlElement(name="option")
private List<ProblemElement> problemElement = new ArrayList<ProblemElement>();
}
ProblemElement
package forum10531285;
import javax.xml.bind.annotation.*;
@XmlType(name = "ProblemElement" )
@XmlAccessorType(XmlAccessType.FIELD)
public class ProblemElement {
@XmlValue
private String option;
}
Demo
package forum10531285;
import java.io.File;
import javax.xml.bind.*;
public class Demo {
public static void main(String[] args) throws Exception {
JAXBContext jc = JAXBContext.newInstance(Root.class);
Unmarshaller unmarshaller = jc.createUnmarshaller();
File xml = new File("src/forum10531285/input.xml");
Root root = (Root) unmarshaller.unmarshal(xml);
Marshaller marshaller = jc.createMarshaller();
marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true);
marshaller.marshal(root, System.out);
}
}
input.xml/Output
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<root>
<subElement>
<a>an instance</a>
<b>another instance</b>
<problemElement>
<option>1st instance</option>
<option>2nd instance</option>
<option>3rd instance</option>
</problemElement>
</subElement>
<subElement>
<a></a>
<b></b>
<problemElement>
<option>instance</option>
</problemElement>
</subElement>
</root>
Upvotes: 3
Reputation: 1944
Sorry but... your ProblemElement may have an indefinite number of options? If that's the case then you should code this instead of your ProblemElement class:
public class ProblemElement {
private List<String> options;
public List<String> getOptions() {
return options;
}
// other stuff here
}
otherwise your JAXBinding will retrieve only the last option in the XML, in this case the 3rd. Of course you should rewrite your binding annotations accordingly.
Upvotes: 2