JAXB XmlElements 使用方法

本文介绍如何使用JAXB的@XmlElements注解映射XML Schema中的选择元素,包括多种类型的示例,如地址、电话号码及备注。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

1.以下是官方文档和实例
 
javax.xml.bind.annotation

Annotation Type XmlElements



  • @Retention(value=RUNTIME)
    @Target(value={FIELD,METHOD})
    public @interface XmlElements

    A container for multiple @XmlElement annotations. Multiple annotations of the same type are not allowed on a program element. This annotation therefore serves as a container annotation for multiple @XmlElements as follows: 

     @XmlElements({ @XmlElement(...),@XmlElement(...) })
     

    The @XmlElements annnotation can be used with the following program elements:

    • a JavaBean property
    • non static, non transient field
    This annotation is intended for annotation a JavaBean collection property (e.g. List). 

    Usage

    The usage is subject to the following constraints: 

    • This annotation can be used with the following        annotations: @XmlIDREF, @XmlElementWrapper.
    • If @XmlIDREF is also specified on the JavaBean property,        then each @XmlElement.type() must contain a JavaBean        property annotated with @XmlID.

    See "Package Specification" in javax.xml.bind.package javadoc for additional common information.


    Example 1: Map to a list of elements

        // Mapped code fragment
        public class Foo {
            @XmlElements(
                @XmlElement(name="A", type=Integer.class),
                @XmlElement(name="B", type=Float.class)
             }
             public List items;
        }
    
        <!-- XML Representation for a List of {1,2.5}
                XML output is not wrapped using another element -->
        ...
        <A> 1 </A>
        <B> 2.5 </B>
        ...
    
        <!-- XML Schema fragment -->
        <xs:complexType name="Foo">
          <xs:sequence>
            <xs:choice minOccurs="0" maxOccurs="unbounded">
              <xs:element name="A" type="xs:int"/>
              <xs:element name="B" type="xs:float"/>
            <xs:choice>
          </xs:sequence>
        </xs:complexType>
    
     

    Example 2: Map to a list of elements wrapped with another element 

        // Mapped code fragment
        public class Foo {
            @XmlElementWrapper(name="bar")
            @XmlElements(
                @XmlElement(name="A", type=Integer.class),
                @XmlElement(name="B", type=Float.class)
            }
            public List items;
        }
    
        <!-- XML Schema fragment -->
        <xs:complexType name="Foo">
          <xs:sequence>
            <xs:element name="bar">
              <xs:complexType>
                <xs:choice minOccurs="0" maxOccurs="unbounded">
                  <xs:element name="A" type="xs:int"/>
                  <xs:element name="B" type="xs:float"/>
                </xs:choice>
              </xs:complexType>
            </xs:element>
          </xs:sequence>
        </xs:complexType>
     

    Example 3: Change element name based on type using an adapter. 

        class Foo {
           @XmlJavaTypeAdapter(QtoPAdapter.class)
           @XmlElements({
               @XmlElement(name="A",type=PX.class),
               @XmlElement(name="B",type=PY.class)
           })
           Q bar;
        }
    
        @XmlType abstract class P {...}
        @XmlType(name="PX") class PX extends P {...}
        @XmlType(name="PY") class PY extends P {...}
    
        <!-- XML Schema fragment -->
        <xs:complexType name="Foo">
          <xs:sequence>
            <xs:element name="bar">
              <xs:complexType>
                <xs:choice minOccurs="0" maxOccurs="unbounded">
                  <xs:element name="A" type="PX"/>
                  <xs:element name="B" type="PY"/>
                </xs:choice>
              </xs:complexType>
            </xs:element>
          </xs:sequence>
        </xs:complexType>
     
    Since:
    JAXB2.0

    2.引用他人的示例

   

JAXB and XSD Choice: @XmlElements

XML Schema has the concept of a choice element.  The choice element indicates that one of the elements defined within the choice may occur at this point in the XML document.  In this example I will demonstrate how easily this can be mapped using JAXB.


XML Schema

We will map our object model to the following XML schema that contains a choice structure.  In this XML schema the choice structure means that after the name element, one of the following elements may occur:  address, phone-number, or note.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
<? xml version = "1.0" encoding = "UTF-8" ?>
< xsd:schema xmlns:xsd = "http://www.w3.org/2001/XMLSchema" >
     < xsd:element name = "customer" type = "customer" />
     < xsd:complexType name = "customer" >
         < xsd:sequence >
             < xsd:element name = "name" type = "xsd:string" minOccurs = "0" />
             < xsd:choice >
                 < xsd:element name = "address" type = "address" />
                 < xsd:element name = "phone-number" type = "phoneNumber" />
                 < xsd:element name = "note" type = "xsd:string" />
             </ xsd:choice >
         </ xsd:sequence >
     </ xsd:complexType >
     < xsd:complexType name = "address" >
         < xsd:sequence >
             < xsd:element name = "city" type = "xsd:string" minOccurs = "0" />
             < xsd:element name = "street" type = "xsd:string" minOccurs = "0" />
         </ xsd:sequence >
     </ xsd:complexType >
     < xsd:complexType name = "phoneNumber" >
         < xsd:simpleContent >
             < xsd:extension base = "xsd:string" >
                 < xsd:attribute name = "type" type = "xsd:string" />
             </ xsd:extension >
         </ xsd:simpleContent >
     </ xsd:complexType >
</ xsd:schema >

Java Model

We will use the following domain model for this example.  The model represents information about a customer.

Customer

Our Customer object has a property called "contactInfo" of type Object that is intended to hold some sort of information related to contacting that customer.  In this example that data can be in the form of a domain object (Address or PhoneNumber) or just a String.

We will use the @XmlElements annotation to map to the choice structure.  Inside @XmlElements are multiple @XmlElement annotations that link a element with a given name and namespace to a class.  During a marshal operation the type of object held by the "contactInfo" property will dictate the element produced, and during an unmarshal operation the element information will dictate what type of object is instantiated.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
package blog.choice;
  
import javax.xml.bind.annotation.*;
  
@XmlAccessorType (XmlAccessType.FIELD)
public class Customer {
  
     private String name;
  
     @XmlElements (value = { 
             @XmlElement (name= "address"
                         type=Address. class ),
             @XmlElement (name= "phone-number"
                         type=PhoneNumber. class ),
             @XmlElement (name= "note"
                         type=String. class )
     })
     private Object contactInfo;
  
}

Address

1
2
3
4
5
6
7
8
9
package blog.choice;
  
public class Address {
  
     private String street;
  
     private String city;
  
}

PhoneNumber

1
2
3
4
5
6
7
8
9
10
11
12
13
14
package blog.choice;
  
import javax.xml.bind.annotation.*;
  
@XmlAccessorType (XmlAccessType.FIELD)
public class PhoneNumber {
  
     @XmlAttribute 
     private String type;
  
     @XmlValue 
     private String number;
  
}

Demo Code

Customer with Address

First we will set an instance of Address on the "contactInfo" property:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
package blog.choice;
  
import javax.xml.bind.*;
  
public class DemoWithAddress {
  
     public static void main(String[] args) throws Exception {
         Customer customer = new Customer();
         customer.setName( "Jane Doe" );
  
         Address address = new Address();
         address.setStreet( "1 A Street" );
         address.setCity( "Any Town" );
         customer.setContactInfo(address);
  
         JAXBContext jc = JAXBContext.newInstance(Customer. class , PhoneNumber. class , Address. class );
         Marshaller marshaller = jc.createMarshaller();
         marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true );
         marshaller.marshal(customer, System.out);
     }
  
}

This will result in the following XML:

1
2
3
4
5
6
7
< customer >
    < name >Jane Doe</ name >
    < address >
       < city >Any Town</ city >
       < street >1 A Street</ street >
    </ address >
</ customer >

Customer with PhoneNumber

Next we will set an instance of PhoneNumber on the "contactInfo" property :

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
package blog.choice;
  
import javax.xml.bind.*;
  
public class DemoWithPhoneNumber {
  
     public static void main(String[] args) throws Exception {
         Customer customer = new Customer();
         customer.setName( "Jane Doe" );
  
         PhoneNumber phoneNumber = new PhoneNumber();
         phoneNumber.setType( "work" );
         phoneNumber.setNumber( "555-1111" );
         customer.setContactInfo(phoneNumber);
  
         JAXBContext jc = JAXBContext.newInstance(Customer. class , PhoneNumber. class , Address. class );
         Marshaller marshaller = jc.createMarshaller();
         marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true );
         marshaller.marshal(customer, System.out);
     }
  
}

This will result in the following XML:

1
2
3
4
< customer >
    < name >Jane Doe</ name >
    < phone-number type = "work" >555-1111</ phone-number >
</ customer >

Customer with String

Finally we will set an instance of String on the "contactInfo" property:


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
package blog.choice;
  
import javax.xml.bind.*;
  
public class DemoWithString {
  
     public static void main(String[] args) throws Exception {
         Customer customer = new Customer();
         customer.setName( "Jane Doe" );
  
         customer.setContactInfo( "jane.doe@example.com" );
  
         JAXBContext jc = JAXBContext.newInstance(Customer. class , PhoneNumber. class , Address. class );
         Marshaller marshaller = jc.createMarshaller();
         marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true );
         marshaller.marshal(customer, System.out);
     }
  
}

This will result in the following XML:

1
2
3
4
< customer >
    < name >Jane Doe</ name >
    < note >jane.doe@example.com</ note >
</ customer

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值