[英]Mapping XMLs with different schemas to the same classes using JAXB
I have these two types of XMLs with no predefined schemas:我有这两种没有预定义模式的 XML:
<root-a>
<a-item id="a1">
<name>Name of A1</name>
<a-item id="a11">
<name>Name of A11</name>
</a-item>
<a-item id="a12">
<name>Name of A12</name>
<a-item id="a121">
<name>Name of A121</name>
</a-item>
<a-item id="a122">
<name>Name of A122</name>
</a-item>
</a-item>
</a-item>
<a-item id="a2">
<name>Name of A2</name>
</a-item>
</root-a>
<root-b>
<b-item id="b1">
<name>Name of B1</name>
<b-item id="b11">
<name>Name of B11</name>
</b-item>
<!-- etc., similar to A -->
</b-item>
</root-b>
The items can be nested to an arbitrary depth.这些项目可以嵌套到任意深度。 The structure is the same, but the name of the root element and of the item elements is different.结构相同,但根元素和项目元素的名称不同。 How can I map it to a single Java class structure, eg.如何将其映射到单个 Java 类结构,例如。 like this one (getters and setters omitted) using JAXB:像这样(省略 getter 和 setter)使用 JAXB:
public class Root {
private List<Item> items;
}
public class Item {
private String id;
private String name;
private List<Item> items;
}
I can map just one of the XML structures using JAXB annotations, but I don't know how to do it to accommodate both XMLs at the same time.我可以使用 JAXB 注释仅映射一个 XML 结构,但我不知道如何同时适应这两个 XML。 I could create a parallel hierarchy for A and B with a common interface, but I hope there's a neater solution.我可以使用通用接口为 A 和 B 创建并行层次结构,但我希望有一个更简洁的解决方案。
Here is XML schema based on your description:这是基于您的描述的 XML 架构:
<?xml version="1.0" encoding="UTF-8"?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" elementFormDefault="qualified" attributeFormDefault="unqualified">
<!-- Root elements -->
<xs:element name="root-a" type="rootAType"/>
<xs:element name="root-b" type="rootBType"/>
<!-- root-a type -->
<xs:complexType name="rootAType">
<xs:sequence>
<xs:element name="a-item" type="itemAType" minOccurs="0" maxOccurs="unbounded"/>
</xs:sequence>
</xs:complexType>
<!-- root-b type -->
<xs:complexType name="rootBType">
<xs:sequence>
<xs:element name="b-item" type="itemBType" minOccurs="0" maxOccurs="unbounded"/>
</xs:sequence>
</xs:complexType>
<!-- abstract item type -->
<xs:complexType name="itemType" abstract="true">
<xs:sequence>
<xs:element name="name" type="xs:string"/>
</xs:sequence>
<xs:attribute name="id" type="xs:string"/>
</xs:complexType>
<!-- item-a type -->
<xs:complexType name="itemAType">
<xs:complexContent>
<xs:extension base="itemType">
<xs:sequence>
<xs:element name="a-item" type="itemAType" minOccurs="0" maxOccurs="unbounded"/>
</xs:sequence>
</xs:extension>
</xs:complexContent>
</xs:complexType>
<!-- item-b type -->
<xs:complexType name="itemBType">
<xs:complexContent>
<xs:extension base="itemType">
<xs:sequence>
<xs:element name="b-item" type="itemBType" minOccurs="0" maxOccurs="unbounded"/>
</xs:sequence>
</xs:extension>
</xs:complexContent>
</xs:complexType>
</xs:schema>
On base of this schema following classes were created:基于此模式创建了以下类:
@XmlAccessorType(XmlAccessType.FIELD)
@XmlType(name = "itemType", propOrder = {
"name"
})
@XmlSeeAlso({
ItemAType.class,
ItemBType.class
})
public abstract class ItemType {
@XmlElement(required = true)
protected String name;
@XmlAttribute(name = "id")
protected String id;
public String getName() {
return name;
}
public void setName(String value) {
this.name = value;
}
public String getId() {
return id;
}
public void setId(String value) {
this.id = value;
}
}
@XmlAccessorType(XmlAccessType.FIELD)
@XmlType(name = "itemAType", propOrder = {
"aItem"
})
public class ItemAType
extends ItemType
{
@XmlElement(name = "a-item")
protected List<ItemAType> aItem;
public List<ItemAType> getAItem() {
if (aItem == null) {
aItem = new ArrayList<ItemAType>();
}
return this.aItem;
}
}
@XmlAccessorType(XmlAccessType.FIELD)
@XmlType(name = "itemBType", propOrder = {
"bItem"
})
public class ItemBType
extends ItemType
{
@XmlElement(name = "b-item")
protected List<ItemBType> bItem;
public List<ItemBType> getBItem() {
if (bItem == null) {
bItem = new ArrayList<ItemBType>();
}
return this.bItem;
}
}
@XmlAccessorType(XmlAccessType.FIELD)
@XmlType(name = "rootAType", propOrder = {
"aItem"
})
public class RootAType {
@XmlElement(name = "a-item")
protected List<ItemAType> aItem;
public List<ItemAType> getAItem() {
if (aItem == null) {
aItem = new ArrayList<ItemAType>();
}
return this.aItem;
}
}
@XmlAccessorType(XmlAccessType.FIELD)
@XmlType(name = "rootBType", propOrder = {
"bItem"
})
public class RootBType {
@XmlElement(name = "b-item")
protected List<ItemBType> bItem;
public List<ItemBType> getBItem() {
if (bItem == null) {
bItem = new ArrayList<ItemBType>();
}
return this.bItem;
}
}
That seems to be a bit too complicated, but if you have more common functionality between a-item and b-item, the structure will become more convenient.这似乎有点太复杂了,但是如果您在 a-item 和 b-item 之间有更多共同的功能,则结构会变得更加方便。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.