JAXB-2 JAXB Annotation 注解

2 JAXB Annotation 注解

Java 对象树和 XML 文档都具备层级结构,JAXB 通过注解(Annotation)对 Java 对象树和 XML 文档的层级结构进行关联;每一个 Java 类都可以对应到一个 XML 节点,Java 类中的字段(field)或属性(get/set)都可以标识为 XML 中的元素(element)或属性(attribute)。
该章节,将会了解 JAXB 注解(Annotation) 的应用场景。

Annotation
Java Class Object
XML Doc

2.1 根节点注解 @XmlRootElement

@XmlRootElement 类级别的注解。将类映射为xml全局元素,也就是根元素。如果要使用 JAXB ,则该注解必不可少

2.1.1 参数说明

@XmlRootElement(name="NodeName", namespace="http://www.w3cschool.org/jaxb2")
  • 参数: name
    默认值: 类名首字母小写(小驼峰)
    说明:name属性用于指定生成元素的名字,若不指定,默认使用类名小写作为元素名。
  • 参数: namespace
    默认值:不显示
    说明:namespace属性用于指定生成的元素所属的命名空间。 namespace 命名空间是 XML 用于区分同名节点的方式之一;引用:XML namespace

2.1.2 使用情景

1、若不指定 XmlRootElement 的 name 参数,默认使用类名首字母小写(小驼峰)作为元素名。

@XmlRootElement
public class Student {
    private String name;
    public String getName() { return name; }
    public void setName(String name) { this.name = name; }
}

生成的XML如下:

<student>
    <name>Tom</name>
    ...
</student>

对应的 XML Schema.

<?xml version="1.0" encoding="UTF-8"?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" elementFormDefault="qualified">
    <xs:element name="studentA" type="Student"/>
    <xs:complexType name="Student">
        <xs:sequence>
            <xs:element name="name" type="xs:string"/>
        </xs:sequence>
    </xs:complexType>
</xs:schema>

2、若指定 XmlRootElement 的 name 属性,则使用 name 指定的名称;

@XmlRootElement(name = "MyStudent")
public class Student {
    private String name;
    // getters, setters
    ... ...
}

生成的XML如下:

<MyStudent>
    <name>Tom</name>
    ...
</MyStudent>

对应的 XML Schema.

<?xml version="1.0" encoding="UTF-8"?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" elementFormDefault="qualified">
    <xs:element name="MyStudent" type="Student"/>
    <xs:complexType name="Student">
        <xs:sequence>
            <xs:element name="name" type="xs:string"/>
        </xs:sequence>
    </xs:complexType>
</xs:schema>

特别地,name 属性支持非 ASCII 码;

@XmlRootElement(name = "学生")
public class Student {
    private String name;
    // getters, setters
    ... ...
}

生成的XML如下:

<学生>
    <name>Tom</name>
    ...
</学生>

对应的 XML Schema.

<?xml version="1.0" encoding="UTF-8"?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" elementFormDefault="qualified">
    <xs:element name="学生" type="Student"/>
    <xs:complexType name="Student">
        <xs:sequence>
            <xs:element name="name" type="xs:string"/>
        </xs:sequence>
    </xs:complexType>
</xs:schema>

注:schema 生成 Java 对应的 xml(带中文元素),需要变更 Java 文件的编码格式。

3、namespace属性用于指定生成的元素所属的命名空间。
namespace 属性一般应用在复杂的对象树和XML文档处理,由于可以使用 name 属性变更对象字段或属性在 XML 的名称,如果出现 XML 元素名称一致但对应的 Java 对象类型不一致时,就需要使用 namespace 属性来限定其中一个 XML 元素,告诉 JAXB 使用该 namespace 所属的 Java 类对 XML 元素进行解析。
下面演示 namespace 属性对应的 XML 文档:

@XmlRootElement(name="Student", namespace="http://www.w3cschool.org/jaxb2")
public class StudentA {
    private String id;
    // getters, setters
    ... ...
}

生成的XML如下:

<ns2:Student xmlns:ns2="http://www.w3cschool.org/jaxb2">
    <ns2:age>22</ns2:age>
    ...
</ns2:Student>

对应的 XSD Schema.

<?xml version="1.0" encoding="UTF-8"?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"
           targetNamespace="http://www.w3cschool.org/jaxb2"
           xmlns:self="http://www.w3cschool.org/jaxb2"
           elementFormDefault="qualified">
    <xs:element name="student" type="self:Student"/>
    <xs:complexType name="Student">
        <xs:sequence>
            <xs:element name="name" type="xs:string"/>
        </xs:sequence>
    </xs:complexType>
</xs:schema>

使用 targetNamespace 将复杂类型 Student 定义在指定命名空间"http://www.w3cschool.org/jaxb2";
定义对命名空间 “http://www.w3cschool.org/jaxb2” 的引用 xmlns:self,在定义元素时,就可以使用在该命名空间的类型 “self:Student”.

下面演示通过 namespace 属性区分不同的 XML 元素。
StudentA.java 类,

public class StudentA {
    private String name;
	// getters, setters
}

Student.java 类,包含 StudentA.java 实例,该实例的 XML 元素名称为 student。

@XmlRootElement
@XmlAccessorType(XmlAccessType.FIELD)
public class Student {
	@XmlAttribute
    private String id;
    @XmlElement(name="student", namespace="http://abcwww.w3cschool.org/jaxb2")
    private StudentA studentA;
    // getters, setters
}    

Student.java 对应的 XML 如下:

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<student id="001" xmlns:ns2="http://www.w3cschool.org/jaxb2">
    <age>22</age>
    <name>Tom</name>
    <ns2:student>
        <name>Tom</name>
    </ns2:student>
</student>

从以上 XML 中可以看出,使用 ns2 前缀对 StudentA.java 的元素进行限定。
对应的 xsd schema 如下:
1、在命名空间 “http://www.w3cschool.org/jaxb2” 的 xsd 文件定义嵌套的 student 类型

<?xml version="1.0" encoding="UTF-8"?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"
           targetNamespace="http://www.w3cschool.org/jaxb2"
           elementFormDefault="qualified">
    <xs:complexType name="Student">
        <xs:sequence>
            <xs:element name="name" type="xs:string"/>
        </xs:sequence>
    </xs:complexType>
</xs:schema>

2、将以上xsd的命名空间引入新的xsd文件,在创建嵌套 student 时,使用以上的命名空间中的student类型。

<?xml version="1.0" encoding="UTF-8"?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"
           xmlns:self="http://www.w3cschool.org/jaxb2"
           elementFormDefault="qualified">
	<xs:element name="student" type="studentType"/>
	<xs:complexType name="studentType">
	  <xs:sequence>
	    <xs:element type="xs:string" name="age"/>
	    <xs:element type="xs:string" name="name"/>
	    <xs:element name="student" type="self:Student"/>
	  </xs:sequence>
	  <xs:attribute type="xs:string" name="id"/>
	</xs:complexType>
</xs:schema>

拓展:JAXB转换对象到XML前缀 ns2:
ns2其实是Marshaller 在转换的时候为未定义的ELEMENT自动生成的一个前缀,因为xml文件里面每一个节点都需要有明确的命名空间,也就是定义这个节点的xsd,否则就像类没有所属的jar包一样没有明确的意义。

2.2 @XmlType

@XmlType 类级别的注解,该注解一般由 JAXB XJC 工具根据 XSD 文档生成;常与@XMLRootElement,@XmlAccessorType一起使用。

2.2.1 参数说明

@XmlType(name = "personinfo", propOrder = {"firstname" ,"lastname"})
  • 参数:name
    默认值:
    说明:定义 XML Schema 中 type 的名称
  • 参数:namespace
    默认值:
    说明:指定Schema中的命名空间
  • 参数:propOrder
    默认值:
    说明:指定映射XML时的节点顺序,使用该属性时,必须列出JavaBean对象中的所有字段,否则会报错。
  • 参数:factoryClass
    默认值:
    说明:指定 UnMarshal 时生成映射类实例所需的工厂类,默认为这个类本身
  • 参数:factoryMethod
    默认值:
    说明:指定工厂类的工厂方法

2.2.2 使用情景

1、name 属性来自 XML Schema
引用:schema-complex
定义 Schema Complex Type(复合元素)时,需要为此指定元素名称;复合元素指包含其他元素及/或属性的 XML 元素。

请看这个复合 XML 元素,“employee”,仅包含其他元素:

<employee>
  <firstname>John</firstname>
  <lastname>Smith</lastname>
</employee> 

在 XML Schema 中,我们有两种方式来定义复合元素:

1) 通过命名此元素,可直接对"employee"元素进行声明,就像这样:

<xs:element name="employee">
  <xs:complexType>
    <xs:sequence>
      <xs:element name="firstname" type="xs:string"/>
      <xs:element name="lastname" type="xs:string"/>
    </xs:sequence>
  </xs:complexType>
</xs:element> 

假如您使用上面所描述的方法,那么仅有 “employee” 可使用所规定的复合类型。请注意其子元素,“firstname” 以及 “lastname”,被包围在指示器 <sequence>中。这意味着子元素必须以它们被声明的次序出现。

经由 JAXB XJC 工具生成的 Java 类一般如下:

@XMLRootElement(name = "employee")
@XmlType(propOrder = {"firstname" ,"lastname"})
public class Employee {
    private String firstname;
    private String lastname;
    ...
}

由于是内嵌的复杂类型,@XmlType 的 name 属性为 “”。

2) “employee” 元素可以使用 type 属性,这个属性的作用是引用要使用的复合类型的名称:

<xs:element name="employee" type="personinfo"/>

<xs:complexType name="personinfo">
  <xs:sequence>
    <xs:element name="firstname" type="xs:string"/>
    <xs:element name="lastname" type="xs:string"/>
  </xs:sequence>
</xs:complexType> 

同样的,JAXB 的 XJC 工具会生成如下的 Java 类:

@XMLRootElement(name = "employee")
@XmlType(name = "personinfo", propOrder = {"firstname" ,"lastname"})
public class Employee {
    private String firstname;
    private String lastname;
    ...
}

此时,独立的复杂类型,@XmlType 的 name 属性填充 schema 中复杂类型的名称 “personinfo”。

2、propOrder 属性指定映射XML时的节点顺序
注意:使用该属性时,必须列出JavaBean对象中的所有字段,否则会报错。

@XMLRootElement
@XmlType(propOrder = {"id" ,"age", "name"})
public class TeacherA {
    private String id;
    private String name;
    private Integer age;
    ...
}

生成的XML如下,生成的顺序是按照propOrder:

<teacherA>
    <id>001</id>
    <age>22</age>
    <name>Tom</name>
</teacherA>

@XmlType 的 propOrder 属性,一般用于接口参数,服务端可以根据参数的强有序生成相关的校验码(如 MD5 等),用于验证接口访问的合法性等。

2.3 @XmlAccessorType

@XmlAccessorType 类级别的注解。定义这个类中的何种类型需要映射到XML。类的类型包括字段(field)、属性(get/set 方法)。该注解将会影响类内部注解的使用方式,如 XmlElement, XmlAttribute等。

2.3.1 参数说明

@XmlAccessorType(XmlAccessType.FIELD)
  • 参数:value
    默认值:XmlAccessType.PUBLIC_MEMBER
    说明:参数 value 可以接受4个指定值,这几个值是枚举类型,方便调用:
    • XmlAccessType.FIELD:映射这个类中的所有字段到XML
    • XmlAccessType.PROPERTY:映射这个类中的属性(get/set方法)到XML
    • XmlAccessType.PUBLIC_MEMBER:将这个类中的所有public的field或property同时映射到XML(默认)
    • XmlAccessType.NONE:不映射

2.3.2 使用情景

使用以下的 XML 作为需求,现在需要编写 Java Bean Class 对此进行转换。

<employee>
  <firstname>John</firstname>
  <lastname>Smith</lastname>
</employee> 

1、value 属性默认 XmlAccessType.PUBLIC_MEMBER

@XmlRootElement
public class Student {
	@XmlElement(name = "firstname")
    public String firstname;
	private String lastname;
	@XmlElement(name = "lastname")
	public String getLastname(){ return lastname; }
	public void setLastname(String lastname){ this.lastname = lastname; }
}

@XmlAccessType 的默认 value 属性值为 XmlAccessType.PUBLIC_MEMBER,会对该类的所有 public 字段(field)或属性(property)进行 XML 的装换,此时可以对 firstname 和 get/set 属性进行 XmlEelement 注解的自定义设置。

2、value 属性使用 XmlAccessType.FIELD

@XmlRootElement
@XmlAccessorType(XmlAccessType.FIELD)
public class Student {
	@XmlElement(name = "firstname")
    private String firstname;
    @XmlElement(name = "lastname")
	private String lastname;
    public String getFirstname(){ return firstname; }
	public void setFirstname(String firstname){ this.firstname = firstname; }
	public String getLastname(){ return lastname; }
	public void setLastname(String lastname){ this.lastname = lastname; }
}

使用 XmlAccessType.FIELD 的 @XmlAccessType,会使代码有更简洁的阅读性;此时只可以对 firstname 和 lastname 字段进行 XmlElement 自定义注解配置。
注:xjc 工具对 schema 文件生成的 Java 代码,默认使用该 XmlAccessType.FIELD 值。

3、value 属性值使用 XmlAccessType.PROPERTY

@XmlRootElement
@XmlAccessorType(XmlAccessType.FIELD)
public class Student {
    private String firstname;
	private String lastname;
	@XmlElement(name = "firstname")
    public String getFirstname(){ return firstname; }
	public void setFirstname(String firstname){ this.firstname = firstname; }
	@XmlElement(name = "lastname")
	public String getLastname(){ return lastname; }
	public void setLastname(String lastname){ this.lastname = lastname; }
}

使用 XmlAccessType.PROPERTY 的 @XmlAccessType,映射这个类中的属性(get/set方法)到 XML;此时,只能对 get/set 属性进行 XmlElement 注解的自定义配置。

2.4 节点标注 @XmlElement

@XmlElement 字段,方法,参数级别的注解。该注解可以将被注解的(非静态)字段,或者被注解的get/set方法对应的字段映射为本地元素,也就是子元素。

2.4.1 参数说明

@XmlElement(name = "", defaultValue = "", nillable = false, required = false)
  • 参数:name
    默认值:
    说明:用于指定映射时的节点名称,指定生成元素的名字,若不指定,默认使用方法名小写作为元素名。
  • 参数:namespace
    默认值:
    说明:指定映射时的节点命名空间
  • 参数:required
    默认值:false
    说明:字段是否必须,默认为false
  • 参数:nillable
    默认值:false
    说明:是否处理空数据,默认为false;默认某一对象字段/属性不进行赋值,不会生成对应的 XML 元素。
  • 参数:type
    默认值:
    说明:定义该字段或属性的关联类型,通过检索类级别注解 @XmlType 的 name 属性进行关联;
  • 参数:defaultValue
    默认值:
    说明:节点的默认值

2.4.2 使用场景

1、使用自定义的节点名称

@XmlRootElement
public class Grade {
    private String id;
    private String name;
    @XmlElement(name = "名称", defaultValue = "一年级", nillable = true, required = true)
    public void setName(String name) {
        this.name = name;
    }
    ...
}

正常情况下得到的XML数据结构:

<grade>
    <id>1001</id>
    <名称>二年级</名称>
    <ranking>1</ranking>
</grade>

对应的 XSD Schema.

<xs:element name="姓名" type="xs:string" nillable="true" default="一年级"/>

或者提供别名

<?xml version="1.0" encoding="UTF-8"?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"
           elementFormDefault="qualified">
    <xs:element name="student" type="Student"/>

    <xs:element name="name" type="xs:string" nillable="false" default="Tom"/>
    <xs:element name="姓名" substitutionGroup="name"/>
    <xs:complexType name="Student">
        <xs:sequence>
            <xs:element ref="name"/>
        </xs:sequence>
    </xs:complexType>
</xs:schema>

注:Schema 生成的 Java Bean XmlElement required 属性默认为 true,不提供属性变更该值。
使用 xjc 对 schema 生成 Java 代码,无法填充 XmlElement 的 name 属性,当 element 出行非 ASCII 码时,xjc 会生成对应的 get/set 属性,此时需要变更相应的 Java 文件的编码方式,如 GBK 等。

2、处理空数据
如果name是空值,转换的 XML 将不会显示该节点;如果标明 nillable=true,则当节点为 null 时,XML 也会显示该 null 信息;

@XmlRootElement
public class Grade {
    private String id;
    private String name;
    @XmlElement(nillable = true)
    public void setName(String name) {
        this.name = name;
    }
    ...
}
// Grade grade = new Grade("1002", null, 2);

得到的XML数据结构如下:

<grade>
    <id>1002</id>
    <name xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:nil="true"/>
    <ranking>2</ranking>
</grade>

2.5 节点属性标注 @XmlAttribute

@XmlAttribute 字段和方法级别的注解。该注解会将字段或get/set方法对应的字段映射成本类对应元素的属性。

2.5.1 参数说明

@XmlAttribute(name="" namespace="" required=false)
  • 参数:name
    默认值:
    说明:用于指定映射时的节点属性名称,若不指定,默认使用方法名小写作为元素名。
  • 参数:namespace
    默认值:
    说明:指定映射时的节点属性命名空间
  • 参数:required
    默认值:false
    说明:该属性是否必须,默认为false

2.5.2 使用情景

@XmlRootElement
public class Desk {
    private String id;
    private String owner;
    @XmlAttribute
    public void setId(String id) {
        this.id = id;
    }
    ...
}

生成的XML如下:

<desk id="004">
    <owner>Tom</owner>
</desk>

2.6 节点不被映射 @XmlTransient

@XmlTrasient 类,字段,方法级别的注解。定义某一字段或属性不需要被映射。该注解与所有其他JAXB注释相互排斥,也就是说与其他注释连用就会报错。 和某些框架中的Ignore注解相同。
不能和其他注解合用

@XmlTransient
@XmlElement
public void setIsbn(String isbn) {
    this.isbn = isbn;
}
javax.xml.bind.DataBindingException: com.sun.xml.internal.bind.v2.runtime.IllegalAnnotationsException: 1 counts of IllegalAnnotationExceptions
com.example.demo.lesson4.Book#isbn具有互相排斥的注释 @javax.xml.bind.annotation.XmlTransient 和 @javax.xml.bind.annotation.XmlElement

没有参数

@XmlTransient
private String isbn;

2.7 解组不匹配节点 @XmlAnyElement

引用:XmlAnyElement
字段和方法级别的注解。在将 xml 内容解组到 JAXB 注释类的实例中时,此注释充当 “catch-all” 属性。它通常注释多值的 JavaBean 属性,但它也能够出现在单值的 JavaBean 属性中。在解组(UnMarshall)过程中,与类中用于其他 JavaBean 属性的静态 @XmlElement 或 @XmlElementRef 注释不匹配的每个 xml 元素都将被添加到此 “catch-all” 属性中。
在类及其超类中只能有一个 XmlAnyElement 注释的 JavaBean 属性。

class Foo {
	int a;
	int b;
	@XmlAnyElement
	List<Element> any;
}

它可以按如下方式解组实例:

<foo xmlns:e="extra">
	<a>1</a>
	<e:other />  // this will be bound to DOM, because unmarshalling is orderless
	<b>3</b>
	<e:other />
	<c>5</c>     // this will be bound to DOM, because the annotation doesn't remember namespaces.
</foo>

子类

class Bar extends Foo {
	int c;
	// Foo.getAny() also represents wildcard content for type definition bar.
}

它可以按如下方式解组实例:

<bar xmlns:e="extra">
	<a>1</a>
	<e:other />  // this will be bound to DOM, because unmarshalling is orderless
	<b>3</b>
	<e:other />
	<c>5</c>     // this now goes to Bar.c
	<e:other />  // this will go to Foo.any
</bar>

2.8 解组不匹配属性 @XmlAnyAttribute

引用:XmlAnyAttribute

字段和方法级别的注解。将 JavaBean 属性映射到通配符属性的映射表中。
用法受到以下约束的限制:
最多只能使用 @XmlAnyAttribute 注释类中的一个字段或属性。
属性或字段的类型必须是 java.util.Map。
在处理将解组成为一个值类的属性时,与另一个 JavaBean 属性不存在静态关联的(通过 XmlAttribute)每个属性都被输入 Map<QName,Object> 表示的通配符属性映射表中。属性 QName 是映射表的键。键值是属性的字符串值。

2.9 @XmlRegistry

引用:XmlRegistry
标记具有 XmlElementDecl 的类。

2.10 @XmlElementDecl

引用:XmlElementDecl

Maps a factory method to a XML element.
Usage

The annotation creates a mapping between an XML schema element
declaration and a <i> element factory method </i> that returns a
JAXBElement instance representing the element
declaration. Typically, the element factory method is generated
(and annotated) from a schema into the ObjectFactory class in a
Java package that represents the binding of the element
declaration’s target namespace. Thus, while the annotation syntax(英 ['sɪntæks] 句法) allows @XmlElementDecl to be used on any method, semantically([sɪ’mæntɪkli] adv. 语义上) its use is restricted to annotation of element factory method.

The usage is subject to the following constraints:

  • The class containing the element factory method annotated with @XmlElementDecl must be marked with @XmlRegistry.
  • The element factory method must take one parameter assignable to Object.

Example 1: Annotation on a factory method

      // Example: code fragment
      @XmlRegistry
      class ObjectFactory {
          @XmlElementDecl(name="foo")
          JAXBElement<String> createFoo(String s) { ... }
      }
      <!-- XML input -->
      <foo>string</foo>
      // Example: code fragment corresponding to XML input
      JAXBContext jaxbContext = JAXBContext.newInstance(ObjectFactory.class);
      Unmarshaller unmarshaller = jaxbContext.createUnmarshaller();
      JAXBElement o =
      (JAXBElement)unmarshaller.unmarshal(aboveDocument);
      // print JAXBElement instance to show values
      System.out.println(o.getName());   // prints  "{}foo"
      System.out.println(o.getValue());  // prints  "string"
      System.out.println(o.getValue().getClass()); // prints "java.lang.String"
      <!-- Example: XML schema definition -->
      <xs:element name="foo" type="xs:string"/>

以上代码体现了两个要点:
1、@XmlElementDecl 标注的方法,与 XML Schema 的元素 <element> 一一对应;
2、@XmlElementDecl 所在的方法,所在的类必须标注为 @XmlRegistry

Example 2: Element declaration with non local scope

The following example illustrates the use of scope annotation parameter in binding of element declaration in schema derived code.

The following example may be replaced in a future revision of this javadoc.

      <!-- Example: XML schema definition -->
      <xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema">
        <xs:complexType name="pea">
          <xs:choice maxOccurs="unbounded">
            <xs:element name="foo" type="xs:string"/>
            <xs:element name="bar" type="xs:string"/>
          </xs:choice>
        </xs:complexType>
        <xs:element name="foo" type="xs:int"/>
      </xs:schema>
      // Example: expected default binding
      class Pea {
          @XmlElementRefs({
              @XmlElementRef(name="foo",type=JAXBElement.class)
              @XmlElementRef(name="bar",type=JAXBElement.class)
          })
          List<JAXBElement<String>> fooOrBar;
      }
 
      @XmlRegistry
      class ObjectFactory {
          @XmlElementDecl(scope=Pea.class,name="foo")
          JAXBElement createPeaFoo(String s);
 
          @XmlElementDecl(scope=Pea.class,name="bar")
          JAXBElement createPeaBar(String s);
 
          @XmlElementDecl(name="foo")
          JAXBElement createFoo(Integer i);
      }

Without scope createFoo and createPeaFoo would become ambiguous since both of them map to a XML schema element with the same local name “foo”.

以上介绍了 scope 参数的使用
1、@XmlElementRef 用来描述非限定集合元素 <xs:choice maxOccurs="unbounded">,表示该非限定集合值允许接收指定的类型;
2、当不同层级的 XML 标签重名时,使用 @XmlElementRefscope 参数来明确次级 XML 标签的上级节点类型;ObjectFactory 对象工厂类,声明了如果解组 XML 中,在 Pea 节点下发现有名称为 foo 的节点,利用 createPeaFoo 方法进行将节点数据转换为 JAXBElement。

注:当使用可选元素标签时 <xs:choice>,XML Schema 生成的代码不包含 <xs:choice> 标签限定:

<xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema" elementFormDefault="qualified">
    <!-- Request XML -->
    <xsd:element name="callback-request" type="CallbackRequest"/>

    <xsd:complexType name="CallbackRequest">
        <xsd:choice>
            <xsd:element name="example-v1-params"      type="ExampleV1Params"/>
            <xsd:element name="example-v2-params"      type="ExampleV2Params"/>
        </xsd:choice>
    </xsd:complexType>
</xsd:schema>
@XmlAccessorType(XmlAccessType.FIELD)
@XmlType(name = "CallbackRequest", propOrder = {
    "exampleV1Params",
    "exampleV2Params"
})
public class CallbackRequest {

    @XmlElement(name = "example-v1-params")
    protected ExampleV1Params exampleV1Params;
    @XmlElement(name = "example-v2-params")
    protected ExampleV2Params exampleV2Params;
}

@see XmlRegistry
@since JAXB 2.0

2.11 @XmlElementRefs

引用:XmlElementRefs
标记一个属性,该属性引用带有 XmlElement 或 JAXBElement 的类。

与元素属性(带有 XmlElement 注释的属性)比较,引用属性具有不同的替换语义。在将子类分配给属性时,元素属性将生成带有 @xsi:type 的相同标记名称,而引用属性则生成一个不同的标记名称(子类上的标记名称)。

2.12 @XmlList

引用:XmlList

用来将属性映射到列表简单类型。

用法

@XmlList 注释能够与以下基础数据元素(string, integer, double, …)一起使用:

  • JavaBean 属性
  • 字段

在集合属性仅使用 @XmlElement 进行注释时,将通过元素包装集合中的每一个项。例如,

 @XmlRootElement
 class Foo {
     @XmlElement
     List<String> data;
 }

将生成如下 XML:

<foo>
	<data>abc</data>
	<data>def</data>
</foo>

另一方面,@XmlList 注释允许将多个值表示为单个元素中以空格分隔的标记。例如,

@XmlRootElement
class Foo {
    @XmlElement
    @XmlList
    List<String> data;
}

上述代码将生成如下 XML:

<foo>
	<data>abc def</data>
</foo>

2.13 XmlValue

引用:注释类型 XmlValue
支持将类映射到带有 simpleContent 的 XML 模式复杂类型或 XML 模式简单类型。

  • 如果字段或属性的类型是集合类型,那么集合项类型必须映射到简单模式类型。
  • 如果字段或属性的类型不是集合类型,那么类型必须映射到 XML 模式简单类型。
  • 如果已注释的 JavaBean 属性是映射到 XML 模式构造的唯一类成员,那么该类将被映射到一个简单类型。
  • 如果存在映射到 XML 属性的其他 JavaBean 属性(使用 @XmlValue 注释注释的 JavaBean 除外),那么类将被映射到带有 simpleContent 的复杂类型。

示例 1:将类映射到 XML 模式 simpleType

// Example 1: Code fragment
public class USPrice {
   @XmlValue
   public java.math.BigDecimal price;
}
<!-- Example 1: XML Schema fragment -->
<xs:simpleType name="USPrice">
  <xs:restriction base="xs:decimal"/>
</xs:simpleType>
<!-- Example 1: XML fragment -->
<USPrice>12.0</USPrice>
<!-- Example 1: XML fragment without @XmlValue -->
<USPrice>
	<price>12.0</price>
</USPrice>

示例 2:将类映射到带有 simpleContent的 XML 模式 complexType。

// Example 2: Code fragment
public class InternationalPrice {
    @XmlValue
    public java.math.BigDecimal price;

    @XmlAttribute
    public String currency;
}
<!-- Example 2: XML Schema fragment -->
<xs:complexType name="InternationalPrice">
  <xs:simpleContent>
    <xs:extension base="xs:decimal">
      <xs:attribute name="currency" type="xs:string"/>
    </xs:extension>
  </xs:simpleContent>
</xs:complexType> 
<!-- Example 2: XML fragment -->
<USPrice currency="1000.0">12.0</USPrice>
<!-- Example 2: XML fragment without @XmlValue -->
<USPrice currency="1000.0">
	<price>12.0</price>
</USPrice>

上一章:JAXB-1 JAXB 概述
目录:学习 JAXB
下一章:JAXB-3 JAXB API


  • 2
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值