我有这样的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>
Run Code Online (Sandbox Code Playgroud)
我应该将此构造转换为具有嵌套项目列表的元素,而不是将每个项目转换为多个元素.这是Element类的示例:
class Element {
Integer type;
String property1;
String property2;
Integer itemId;
String itemName;
}
Run Code Online (Sandbox Code Playgroud)
我想在解组后得到它们的清单.对于所有列表元素,Type,property1和property2值应该相同.有没有可能使用JAXB解决这个问题?
Alk*_*ris 18
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();
}
}
}
Run Code Online (Sandbox Code Playgroud)
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;
}
}
Run Code Online (Sandbox Code Playgroud)
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;
}
}
Run Code Online (Sandbox Code Playgroud)
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;
}
}
Run Code Online (Sandbox Code Playgroud)
因为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>
Run Code Online (Sandbox Code Playgroud)
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}]
]
Run Code Online (Sandbox Code Playgroud)
您将需要定义一个自定义XmlAdapter。您的情况中最复杂的部分是您想要将一个 XML 映射element
到多个 JavaElement
对象。这意味着,在 Java 中,您XmlAdapter
需要配置为收集Element
。假设您的示例 XML 片段是文档的一部分:
<document>\n <elements> \n <element>\n ....\n </element>\n <elements>\n</document> \n
Run Code Online (Sandbox Code Playgroud)\n\n然后你需要在Java中配置XmlAdapter
该字段List<Element>
Document
字段:
class Document {\n @XmlJavaTypeAdapter(CustomAdapter.class)\n List<Element> elements;\n}\n
Run Code Online (Sandbox Code Playgroud)\n\n那么你你的CustomAdapter
类可以接收 Element 对象列表(对应于具有嵌套项的实际 XML 结构),并生成具有所需结构的 Element 列表。
有关示例,请检查JAXB XmlAdapter \xe2\x80\x93 自定义编组和解组
\n