使用JAXB解组嵌套的XML元素 [英] Unmarshal nested XML elements with JAXB

查看:80
本文介绍了使用JAXB解组嵌套的XML元素的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我从JAXB开始,我试图读取以下xml以将其映射到类:

I'm starting with JAXB and im trying to read the following xml to map it to a classe:

<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)时,我的麻烦就来了,它可以包含任意数量的元素.我现在正在尝试:

My porblem comes when I try to map the nested elements like abslute, wich can contain any number of elements. I'm trying this right now:

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
                +"}";
    }
}

我得到了简单的元素,但没有嵌套的元素.显然,我无法将包装器一起注释,所以我不知道如何解决它.

I got the simple elements but not the nested one. Apparently I can't annotate to wrappers together, so I don't know how to fix it.

更新: 我正在按照建议尝试此操作.我得到一个IllegalAnnotationExceptions,因为Element $ Location.right不是编译属性,但是我不知道这意味着什么.我是否应该为该元素再创建一个类?

UPDATE: I'm trying this as suggested. I'm getting an IllegalAnnotationExceptions because Element$Location.right is not a compilation property, but i don't know what it means. Should I create one more class for the element?

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处理为每个复杂元素假定一个单独的元素定义.复杂元素是指包含其他元素的元素.

JAXB processing assumes a separate element definition for each complex element. A complex element means an element containing other elements.

您提到的涉及Element $ Location的错误可能表明jaxb例程已在嵌套的Location类中找到字段"right"的注释;在运行时,嵌套类的名称为包含类的名称(在本例中为Element),作为前缀与嵌套类之间用美元符号分隔.

The error you mention, referring to Element$Location, probably indicates the jaxb routines have found the annotation for the field "right" in the nested Location class; at runtime, nested classes have the name of the containing class, in this case Element, as a prefix separated from the nested class by a dollar sign.

要解组(您从xml文本转换为Java代码)上面提供的数据结构,JAXB例程希望找到以下公共类定义:

To unmarshall (translate from xml text to Java code) the data structure you provide above, the JAXB routines would expect to find the following public class definitions:

绝对 元素 地点 对象工厂 相对

Absolute Element Location ObjectFactory Relative

在jaxb编译器生成的Java代码中,main元素定义具有其自己的类以及以下注释:

In the java code the jaxb compiler produces, the main element definition has its own class, and the following annotations:

@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)具有自己的类,带有以下注释:

The element contained, in this case Location, has its own class with the following annotations:

@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希望找到定义为集合(列表)的元素,因此:

Again, jaxb expects to find public Absolute and Relative classes. Since the absolute-item element can be repeated indefinitely, jaxb expects to find it defined as a collection (List), thus:

@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开发工具都会自动为您处理此问题.为了生成用作以上示例的源代码(我做了一些压缩,编写了以下模式:

In my experience, jaxb schema compiler, xjc, provides the easiest way, by far, to generate classes or use with jaxb. xjc takes an XML schema definition, and translates it into java code for you; you then have only to include the resulting java files in your project. Most Java development tools will handle this for you automatically. To generate the code I used as a source for the examples above (I did some condensing, I wrote the following schema:

<?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>

这篇关于使用JAXB解组嵌套的XML元素的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆