[英]Unmarshal nested XML elements with JAXB
我从JAXB开始,我试图读取以下xml以将其映射到类:
<element id="0">
<type>1</type>
<color>0</color>
<size>1</size>
<location>
<absolute>
<absolute-item>top</absolute-item>
<absolute-item>left</absolute-item>
</absolute>
<relative>
<right>0</right>
<left>0</left>
</relative>
</location>
</element>
当我尝试映射诸如abslute之类的嵌套元素时,我的麻烦就来了,它可以包含任意数量的元素。 我现在正在尝试:
public class Element {
@XmlAttribute
private int id;
@XmlElement
private int type;
@XmlElement
private int color;
@XmlElement
private int size;
@XmlElementWrapper(name="absolute")
@XmlElement(name="absolute-item")
private ArrayList<String> absoluteItems;
@Override
public String toString() {
return "Element "+id+" {" +
"type=" + type +
", color=" + color +
", size=" + size +
", Location Relative: "+ absoluteItems
+"}";
}
}
我得到了简单的元素,但没有嵌套的元素。 显然,我无法将包装器注释在一起,因此我不知道如何解决它。
更新:我正在尝试按照建议的方法。 我收到一个IllegalAnnotationExceptions
因为Element $ Location.right不是编译属性,但我不知道这意味着什么。 是否应该为该元素再创建一个类?
public class Element {
@XmlAttribute
private int id;
@XmlElement
private int type;
@XmlElement
private int color;
@XmlElement
private int size;
@XmlElement(name="location")
private Location location;
public static class Location {
@XmlElementWrapper(name="absolute")
@XmlElement(name="absolute-item")
private ArrayList<String> absoluteItems;
@XmlElementWrapper(name="relative")
@XmlElement(name="right")
private int right;
@XmlElement(name="left")
private int left;
@Override
public String toString() {
return "Location{" +
"Absolute=" + absoluteItems +
", relative {right=" + right +
", left=" + left +
"}}";
}
}
JAXB处理为每个复杂元素假定一个单独的元素定义。 复杂元素是指包含其他元素的元素。
您提到的涉及Element $ Location的错误可能表明jaxb例程已在嵌套的Location类中找到字段“ right”的注释; 在运行时,嵌套类具有包含类的名称(在本例中为Element),作为与嵌套类之间用美元符号分隔的前缀。
为了取消编组(从xml文本转换为Java代码)上面提供的数据结构,JAXB例程希望找到以下公共类定义:
绝对元素位置ObjectFactory相对
在jaxb编译器生成的Java代码中,main元素定义具有其自己的类以及以下注释:
@XmlAccessorType(XmlAccessType.FIELD)
@XmlType(name = "", propOrder = {
"type",
"color",
"size",
"location"
})
@XmlRootElement(name = "element")
public class Element
{
@XmlElement(required = true)
protected BigInteger type;
.
. additional element definitions go here
.
// note: location here is a public class
@XmlElement(required = true)
protected Location location;
// the attribute is defined thus:
@XmlAttribute(name = "id")
protected BigInteger id;
/**
* Gets the value of the type property.
* @return BigInteger type code
*/
public BigInteger getType() { return type; }
/**
* Sets the value of the type property.
* @param value BigInteger type code to set
*/
public void setType(BigInteger value) { this.type = value; }
.
. all other getters and setters defined here
.
}
在这种情况下,元素包含的元素具有自己的类,带有以下注释:
@XmlAccessorType(XmlAccessType.FIELD)
@XmlType(name = "Location", propOrder = {
"absolute",
"relative"
})
public class Location
{
protected Absolute absolute;
protected Relative relative;
.
. getters and setters go here: note these fields have no
. annotations
}
再次,jaxb希望找到公共的Absolute和Relative类。 由于absolute-item元素可以无限期重复,因此jaxb希望找到定义为集合(List)的元素,因此:
@XmlAccessorType(XmlAccessType.FIELD)
@XmlType(name = "Absolute", propOrder = {
"absoluteItem"
})
public class Absolute
{
@XmlElement(name = "absolute-item", required = true)
protected List<String> absoluteItem;
/**
* Gets the value of the absoluteItem property.
*
* <p>This accessor returns a reference to the live list; any
* modification to the returned list will be reflected in the
* JAXB object.
* This is why there is not a setter for absoluteItem.
*
* To add a new item, do as follows:
* getAbsoluteItem().add(newItem)
*/
public List<String> getAbsoluteItem()
{
if (absoluteItem == null)
absoluteItem = new ArrayList <> ();
return this.absoluteItem;
}
}
以我的经验,到目前为止,jaxb模式编译器xjc提供了生成类或与jaxb一起使用的最简单方法。 xjc采用XML模式定义,并为您将其转换为Java代码; 然后,您只需要在项目中包括生成的Java文件即可。 大多数Java开发工具都会自动为您处理此问题。 为了生成用作以上示例的源代码(我做了一些压缩,编写了以下模式:
<?xml version="1.0" encoding="UTF-8"?>
<!--
Component ==> example for stack overflow
Purpose: show how the jaxb compiler works
-->
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"
xmlns:jxb="http://java.sun.com/xml/ns/jaxb"
xmlns:desc = "http://sox.org/element"
targetNamespace = "http://sox.org/element"
jxb:version="2.0">
<xs:element name="element">
<xs:complexType>
<xs:sequence>
<xs:element name = "type" type = "xs:integer" />
<xs:element name = "color" type = "xs:integer" />
<xs:element name = "size" type = "xs:integer" />
<xs:element name = "location" type = "desc:Location" />
</xs:sequence>
<xs:attribute name="id" type="xs:integer" use="optional"
default="0" />
</xs:complexType>
</xs:element>
<xs:complexType name="Location">
<xs:sequence>
<xs:element name = "absolute" type = "desc:Absolute"
minOccurs="0" />
<xs:element name = "relative" type = "desc:Relative"
minOccurs="0" />
</xs:sequence>
</xs:complexType>
<xs:complexType name="Absolute">
<xs:sequence>
<xs:element name="absolute-item" type="xs:string"
maxOccurs="unbounded" />
</xs:sequence>
</xs:complexType>
<xs:complexType name="Relative">
<xs:sequence>
<xs:element name="right" type="xs:string" />
<xs:element name="left" type="xs:string" />
</xs:sequence>
</xs:complexType>
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.