我从 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>
当我尝试映射嵌套元素(例如绝对元素)时,我的问题就出现了,它可以包含任意数量的 <absolute-item>
元素。我现在正在尝试:
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 不是编译属性,但我不知道它意味着什么。我是否应该为 <relative>
再创建一个类元素?
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 例程将期望找到以下公共(public)类定义:
绝对 元素 地点 对象工厂 相对
在 jaxb 编译器生成的 java 代码中,主要元素定义有自己的类,以及以下注释:
@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
.
}
所包含的元素(在本例中为 Location)有自己的类,并带有以下注释:
@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 希望找到公共(public) 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>
关于java - 使用 JAXB 解码嵌套 XML 元素,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/49181125/