[英]Unmarshalling nested list of xml items using JAXB
我有这样的xml结构,我需要使用JAXB转换为java对象:
<elements>
<elemet>
<type></type>
<property1></property1>
<property2></property2>
<items>
<item>
<id></id>
<name></name>
</item>
...
<item>
<id></id>
<name></name>
</item>
</items>
</element>
</elements>
我应该将此构造转换为具有嵌套项目列表的元素,而不是将每个项目转换为多个元素。 这是Element类的示例:
class Element {
Integer type;
String property1;
String property2;
Integer itemId;
String itemName;
}
我想在解组后得到它们的清单。 对于所有列表元素,Type,property1和property2值应该相同。 有没有可能使用JAXB解决这个问题?
Main.java
import java.io.StringReader;
import java.util.ArrayList;
import java.util.List;
import javax.xml.bind.JAXBContext;
import javax.xml.bind.JAXBException;
import javax.xml.bind.Marshaller;
import javax.xml.bind.Unmarshaller;
public class Main {
public static void main(String[] args) {
List<Element> elementList = new ArrayList<Element>();
List<Item> itemList = new ArrayList<Item>();
Element element1 = new Element();
Element element2 = new Element();
Item item1 = new Item();
Item item2 = new Item();
Elements elements = new Elements();
item1.setId(1);
item1.setName("Test1");
item2.setId(2);
item2.setName("Test2");
itemList.add(item1);
itemList.add(item2);
element1.setProperty1("prop1");
element1.setProperty2("prop2");
element1.setType(2);
element1.setItems(itemList);
element2.setProperty1("prop11");
element2.setProperty2("prop22");
element2.setType(22);
element2.setItems(itemList);
elementList.add(element1);
elementList.add(element2);
elements.setElements(elementList);
try {
System.out.println("------- Object to XML -----------\n");
JAXBContext jaxbContext = JAXBContext.newInstance(Elements.class);
Marshaller jaxbMarshaller = jaxbContext.createMarshaller();
// output pretty printed
jaxbMarshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true);
jaxbMarshaller.marshal(elements, System.out);
System.out.println("\n------- XML to Object -----------\n");
String xml = "<elements><element><items><item><id>1</id><name>Test1</name></item><item><id>2</id><name>Test2</name></item></items><property1>prop1</property1><property2>prop2</property2><type>2</type></element><element><items><item><id>1</id><name>Test1</name></item><item><id>2</id><name>Test2</name></item></items><property1>prop11</property1><property2>prop22</property2><type>22</type></element></elements>";
StringReader reader = new StringReader(xml);
Unmarshaller jaxbUnmarshaller = jaxbContext.createUnmarshaller();
Elements elementsOut = (Elements) jaxbUnmarshaller.unmarshal(reader);
System.out.println(elementsOut);
} catch (JAXBException e) {
e.printStackTrace();
}
}
}
Elements.java
import java.lang.reflect.Field;
import java.util.List;
import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlRootElement;
@XmlRootElement(name="elements")
public class Elements {
List<Element> elements;
@XmlElement(name="element")
public List<Element> getElements() {
return elements;
}
public void setElements(List<Element> elements) {
this.elements = elements;
}
@Override
public String toString() {
Field[] fields = this.getClass().getDeclaredFields();
String res = "";
try {
for (Field field : fields) {
res += field.getName() + " :\n" + field.get(this);
}
} catch (Exception e) {
e.printStackTrace();
}
return res;
}
}
Element.java
import java.lang.reflect.Field;
import java.util.List;
import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlElementWrapper;
public class Element {
Integer type;
String property1;
String property2;
List<Item> items;
public Integer getType() {
return type;
}
public void setType(Integer type) {
this.type = type;
}
public String getProperty1() {
return property1;
}
public void setProperty1(String property1) {
this.property1 = property1;
}
public String getProperty2() {
return property2;
}
public void setProperty2(String property2) {
this.property2 = property2;
}
@XmlElementWrapper(name="items")
@XmlElement(name = "item")
public List<Item> getItems() {
return items;
}
public void setItems(List<Item> items) {
this.items = items;
}
@Override
public String toString() {
Field[] fields = this.getClass().getDeclaredFields();
String res = "\n";
try {
for (Field field : fields) {
res += field.getName() + " : " + field.get(this) + "\n";
}
} catch (Exception e) {
e.printStackTrace();
}
return res;
}
}
Item.java
import java.lang.reflect.Field;
public class Item {
Integer id;
String name;
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
@Override
public String toString() {
Field[] fields = this.getClass().getDeclaredFields();
String res = "{";
try {
for (Field field : fields) {
res += field.getName() + " : " + field.get(this);
}
res += "}";
} catch (Exception e) {
e.printStackTrace();
}
return res;
}
}
因为elements
标记是root元素,所以你不能使用@XmlElementWrapper
,但是items
不是root,所以你可以在那里使用它,因此你不必实现Items
类。 忽略toString
实现,只是以有意义的方式打印对象。
对象到XML输出
------- XML对象-----------
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<elements>
<element>
<items>
<item>
<id>1</id>
<name>Test1</name>
</item>
<item>
<id>2</id>
<name>Test2</name>
</item>
</items>
<property1>prop1</property1>
<property2>prop2</property2>
<type>2</type>
</element>
<element>
<items>
<item>
<id>1</id>
<name>Test1</name>
</item>
<item>
<id>2</id>
<name>Test2</name>
</item>
</items>
<property1>prop11</property1>
<property2>prop22</property2>
<type>22</type>
</element>
</elements>
XML到对象输出
------- XML to Object -----------
elements :
[
type : 2
property1 : prop1
property2 : prop2
items : [{id : 1name : Test1}, {id : 2name : Test2}]
,
type : 22
property1 : prop11
property2 : prop22
items : [{id : 1name : Test1}, {id : 2name : Test2}]
]
您需要定义自定义XmlAdapter 。 您的案例中复杂的部分是您希望将一个XML element
映射到多个Java Element
对象。 这意味着,在Java中,需要配置XmlAdapter
以收集Element
对象。 假设您的示例XML片段是文档的一部分:
<document>
<elements>
<element>
....
</element>
<elements>
</document>
然后,您需要为Java Document
类中的List<Element>
字段配置XmlAdapter
:
class Document {
@XmlJavaTypeAdapter(CustomAdapter.class)
List<Element> elements;
}
然后,您的CustomAdapter
类可以接收Element对象列表(对应于具有嵌套项的实际XML结构),并生成具有所需结构的Element列表。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.