Reputation: 8923
The xml structure I am trying to parse is:
<contentFiles>
<contentFile>
<fileNumbers>
<fileNumber>123<fileNumber>
</fileNumbers>
</contentFile>
<contentFile/>
<contentFiles>
How do I parse this using JAXB ?
I used the annotations on getters described above but I only get the last element in the multiples of FileNumbers saved. I want to save all the elements of FileNumbers in the list. How do I do this ?
EDIT:::
@XmlRootElement(name = "contentFiles")
public class RtSuperQuickMetadata
{
private List<RtSuperQuickMetadataItem> rtSuperQuickMetadataItems;
@XmlElement(name = "contentFile")
public final List<RtSuperQuickMetadataItem> getRtSuperQuickMetadataItems()
{
return rtSuperQuickMetadataItems;
}
// Setter
}
public class RtSuperQuickMetadataItem
{
private List<FileNumber> fileNumbers;
public RtSuperQuickMetadataItem()
{
fileNumbers = new ArrayList<FileNumber>();
}
@XmlElement(name = "fileNumbers")
public List<FileNumber> getFileNumbers()
{
return fileNumbers;
}
//setter
}
@XmlRootElement(name="fileNumber")
public class FileNumber
{
private String fileNumber;
/**
* Default no-arg constructor.
*/
public FileNumber()
{
// public no-arg constructor for JAXB
}
/**
* Accept a filenumber as constructor arg.
* @param fileNumber is the fileNumber
*/
public FileNumber(final String fileNumber)
{
this.fileNumber = fileNumber;
}
/**
* Getter.
* @return the fileNumber
*/
//@XmlElement(name = "fileNumber")
public final String getFileNumber()
{
return fileNumber;
}
/**
* Setter.
* @param fileNumber to be set.
*/
public final void setFileNumber(final String fileNumber)
{
this.fileNumber = fileNumber;
}
@Override
public final String toString()
{
return fileNumber;
}
}
Upvotes: 1
Views: 2396
Reputation: 285405
The reason I'm asking for a larger XML file representation is that your code will completely depend on the requirements of the XML file. For instance, this bit of your code works with the following XML file:
Code:
import java.util.ArrayList;
import java.util.List;
import javax.xml.bind.annotation.*;
import javax.xml.bind.*;
public class JaxbTest {
private static final String RESOURCE_NAME = "data.txt";
public static void main(String[] args) {
// marshallTest();
unmarshallTest();
}
private static void unmarshallTest() {
JAXBContext context;
try {
context = JAXBContext.newInstance(RtSuperQuickMetadata.class);
Unmarshaller unmarshaller = context.createUnmarshaller();
RtSuperQuickMetadata metaData = (RtSuperQuickMetadata) unmarshaller
.unmarshal(JaxbTest.class.getResourceAsStream(RESOURCE_NAME));
System.out.println(metaData);
} catch (JAXBException e) {
e.printStackTrace();
}
}
private static void marshallTest() {
RtSuperQuickMetadata data = new RtSuperQuickMetadata();
List<RtSuperQuickMetadataItem> metaItemList = new ArrayList<RtSuperQuickMetadataItem>();
RtSuperQuickMetadataItem metaDataItem = new RtSuperQuickMetadataItem();
List<FileNumber> fileNumbers = new ArrayList<FileNumber>();
fileNumbers.add(new FileNumber("123"));
fileNumbers.add(new FileNumber("124"));
fileNumbers.add(new FileNumber("125"));
fileNumbers.add(new FileNumber("126"));
metaDataItem.setFileNumbers(fileNumbers);
metaItemList.add(metaDataItem);
data.setRtSuperQuickMetadataItems(metaItemList);
JAXBContext context;
try {
context = JAXBContext.newInstance(RtSuperQuickMetadata.class);
Marshaller marshaller = context.createMarshaller();
marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true);
marshaller.marshal(data, System.out);
} catch (JAXBException e) {
e.printStackTrace();
}
}
}
@XmlRootElement(name = "contentFiles")
class RtSuperQuickMetadata {
private List<RtSuperQuickMetadataItem> rtSuperQuickMetadataItems;
@XmlElement(name = "contentFile")
public final List<RtSuperQuickMetadataItem> getRtSuperQuickMetadataItems() {
return rtSuperQuickMetadataItems;
}
public void setRtSuperQuickMetadataItems(
List<RtSuperQuickMetadataItem> rtSuperQuickMetadataItems) {
this.rtSuperQuickMetadataItems = rtSuperQuickMetadataItems;
}
@Override
public String toString() {
return "RtSuperQuickMetadata [rtSuperQuickMetadataItems="
+ rtSuperQuickMetadataItems + "]";
}
}
class RtSuperQuickMetadataItem {
private List<FileNumber> fileNumbers;
public RtSuperQuickMetadataItem() {
fileNumbers = new ArrayList<FileNumber>();
}
@XmlElement(name = "fileNumbers")
public List<FileNumber> getFileNumbers() {
return fileNumbers;
}
public void setFileNumbers(List<FileNumber> fileNumbers) {
this.fileNumbers = fileNumbers;
}
@Override
public String toString() {
return "RtSuperQuickMetadataItem [fileNumbers=" + fileNumbers + "]";
}
}
@XmlRootElement(name = "fileNumber")
class FileNumber {
private String fileNumber;
public FileNumber() {}
public FileNumber(final String fileNumber) {
this.fileNumber = fileNumber;
}
// @XmlElement(name = "fileNumber")
public final String getFileNumber() {
return fileNumber;
}
public final void setFileNumber(final String fileNumber) {
this.fileNumber = fileNumber;
}
@Override
public final String toString() {
return fileNumber;
}
}
The xml file, assuming it's in the same directory as your class files: jaxbTest.xml
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<contentFiles>
<contentFile>
<fileNumbers>
<fileNumber>123</fileNumber>
</fileNumbers>
<fileNumbers>
<fileNumber>124</fileNumber>
</fileNumbers>
<fileNumbers>
<fileNumber>125</fileNumber>
</fileNumbers>
<fileNumbers>
<fileNumber>126</fileNumber>
</fileNumbers>
</contentFile>
</contentFiles>
However if this is not your desired XML structure, then the code must change.
Edit
If you want to not nest each fileNumber element in a fileNumbers element, then get rid of the FileNumbers class and instead use a List<String>
with the @XmlElementWrapper
annotation.
@XmlElementWrapper(name = "fileNumbers")
@XmlElement(name = "fileNumber")
public List<String> getFileNumbers() {
return fileNumbers;
}
For instance please check out this code:
import java.util.ArrayList;
import java.util.List;
import javax.xml.bind.annotation.*;
import javax.xml.bind.*;
public class JaxbTest {
private static final String RESOURCE_NAME = "data.xml";
public static void main(String[] args) {
// marshallTest();
unmarshallTest();
}
private static void unmarshallTest() {
JAXBContext context;
try {
context = JAXBContext.newInstance(RtSuperQuickMetadata.class);
Unmarshaller unmarshaller = context.createUnmarshaller();
RtSuperQuickMetadata metaData = (RtSuperQuickMetadata) unmarshaller
.unmarshal(JaxbTest.class.getResourceAsStream(RESOURCE_NAME));
System.out.println(metaData);
} catch (JAXBException e) {
e.printStackTrace();
}
}
private static void marshallTest() {
RtSuperQuickMetadata data = new RtSuperQuickMetadata();
List<RtSuperQuickMetadataItem> metaItemList = new ArrayList<RtSuperQuickMetadataItem>();
RtSuperQuickMetadataItem metaDataItem = new RtSuperQuickMetadataItem();
// List<FileNumber> fileNumbers = new ArrayList<FileNumber>();
// fileNumbers.add(new FileNumber("123"));
// fileNumbers.add(new FileNumber("124"));
// fileNumbers.add(new FileNumber("125"));
// fileNumbers.add(new FileNumber("126"));
List<String> fileNumbers = new ArrayList<String>();
fileNumbers.add("123");
fileNumbers.add("124");
fileNumbers.add("125");
fileNumbers.add("126");
metaDataItem.setFileNumbers(fileNumbers);
metaItemList.add(metaDataItem);
data.setRtSuperQuickMetadataItems(metaItemList);
JAXBContext context;
try {
context = JAXBContext.newInstance(RtSuperQuickMetadata.class);
Marshaller marshaller = context.createMarshaller();
marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true);
marshaller.marshal(data, System.out);
} catch (JAXBException e) {
e.printStackTrace();
}
}
}
@XmlRootElement(name = "contentFiles")
class RtSuperQuickMetadata {
private List<RtSuperQuickMetadataItem> rtSuperQuickMetadataItems;
@XmlElement(name = "contentFile")
public final List<RtSuperQuickMetadataItem> getRtSuperQuickMetadataItems() {
return rtSuperQuickMetadataItems;
}
public void setRtSuperQuickMetadataItems(
List<RtSuperQuickMetadataItem> rtSuperQuickMetadataItems) {
this.rtSuperQuickMetadataItems = rtSuperQuickMetadataItems;
}
@Override
public String toString() {
return "RtSuperQuickMetadata [rtSuperQuickMetadataItems="
+ rtSuperQuickMetadataItems + "]";
}
}
class RtSuperQuickMetadataItem {
private List<String> fileNumbers;
public RtSuperQuickMetadataItem() {
fileNumbers = new ArrayList<String>();
}
@XmlElementWrapper(name = "fileNumbers")
@XmlElement(name = "fileNumber")
public List<String> getFileNumbers() {
return fileNumbers;
}
public void setFileNumbers(List<String> fileNumbers) {
this.fileNumbers = fileNumbers;
}
@Override
public String toString() {
return "RtSuperQuickMetadataItem [fileNumbers=" + fileNumbers + "]";
}
}
Will work with this XML:
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<contentFiles>
<contentFile>
<fileNumbers>
<fileNumber>123</fileNumber>
<fileNumber>124</fileNumber>
<fileNumber>125</fileNumber>
<fileNumber>126</fileNumber>
</fileNumbers>
</contentFile>
</contentFiles>
Upvotes: 1
Reputation: 43827
It's been a while since I've done JAX-B but I think this should do the trick (only relevant sections posted). If you want to avoid creating the FileNumberList class you can probably do so with an adapter but that will be more work than it is worth.
public class RtSuperQuickMetadataItem {
@XmlElement
public FileNumberList getFileNumbers() {
}
}
public class FileNumberList {
@XmlElement(name="fileNumber")
public List<String> getList() {
}
}
Upvotes: 0