XML-схема
Схема XML ниже содержит три корневых элемента: покупатель , адрес выставления счета и адрес доставки . Элемент customer имеет анонимный сложный тип, в то время как адрес выставления счета и адрес доставки имеют одинаковый именованный тип (тип адреса ).
| 01 02 03 04 05 06 07 08 09 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 | <?xmlversion="1.0"encoding="UTF-8"?><xs:schema    elementFormDefault="qualified">    <xs:elementname="customer">        <xs:complexType>            <xs:sequence>                <xs:elementref="billing-address"/>                <xs:elementref="shipping-address"/>            </xs:sequence>        </xs:complexType>    </xs:element>    <xs:complexTypename="address-type">        <xs:sequence>            <xs:elementname="street"type="xs:string"/>        </xs:sequence>    </xs:complexType>    <xs:elementname="billing-address"type="address-type"/>    <xs:elementname="shipping-address"type="address-type"/></xs:schema> | 
Сгенерированная модель
Ниже приведена модель JAXB, созданная на основе схемы XML. Те же понятия применяются при добавлении аннотаций JAXB к существующей модели Java.
Клиент
Классы домена JAXB соответствуют сложным типам. Поскольку элемент customer имеет анонимный сложный тип, класс Customer имеет аннотацию @XmlRootElement . Это потому, что только один элемент XML может быть связан с анонимным типом.
| 01 02 03 04 05 06 07 08 09 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 | packageorg.example.customer;importjavax.xml.bind.annotation.*;@XmlAccessorType(XmlAccessType.FIELD)@XmlType(name = "", propOrder = {"billingAddress","shippingAddress"})@XmlRootElement(name = "customer")publicclassCustomer {    @XmlElement(name = "billing-address", required = true)    protectedAddressType billingAddress;    @XmlElement(name = "shipping-address", required = true)    protectedAddressType shippingAddress;    publicAddressType getBillingAddress() {        returnbillingAddress;    }    publicvoidsetBillingAddress(AddressType value) {        this.billingAddress = value;    }    publicAddressType getShippingAddress() {        returnshippingAddress;    }    publicvoidsetShippingAddress(AddressType value) {        this.shippingAddress = value;    }} | 
Тип адреса
Опять же, поскольку классы модели JAXB соответствуют сложным типам, класс создается для сложного типа адресного типа . Поскольку для этого именованного сложного типа могут существовать несколько элементов корневого уровня, это не аннотируется @XmlRootElement .
| 01 02 03 04 05 06 07 08 09 10 11 12 13 14 15 16 17 18 19 20 | packageorg.example.customer;importjavax.xml.bind.annotation.*;@XmlAccessorType(XmlAccessType.FIELD)@XmlType(name = "address-type", propOrder = {"street"})publicclassAddressType {    @XmlElement(required = true)    protectedString street;    publicString getStreet() {        returnstreet;    }    publicvoidsetStreet(String value) {        this.street = value;    }} | 
ObjectFactory
Аннотация @XmlElementDecl используется для представления корневых элементов, соответствующих именованным сложным типам. Он помещается в метод фабрики в классе, аннотированном @XmlRegistry (при создании из схемы XML этот класс всегда называется ObjectFactory ). Метод фабрики возвращает объект домена, завернутый в экземпляр JAXBElement. JAXBElement имеет QName, который представляет имя элемента и URI пространства имен.
| 01 02 03 04 05 06 07 08 09 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 | packageorg.example.customer;importjavax.xml.bind.JAXBElement;importjavax.xml.bind.annotation.*;importjavax.xml.namespace.QName;@XmlRegistrypublicclassObjectFactory {    privatefinalstaticQName _BillingAddress_QNAME = newQName("http://www.example.org/customer", "billing-address");    privatefinalstaticQName _ShippingAddress_QNAME = newQName("http://www.example.org/customer", "shipping-address");    publicObjectFactory() {    }    publicCustomer createCustomer() {        returnnewCustomer();    }    publicAddressType createAddressType() {        returnnewAddressType();    }    publicJAXBElement<AddressType> createBillingAddress(AddressType value) {        returnnewJAXBElement<AddressType>(_BillingAddress_QNAME, AddressType.class, null, value);    }    publicJAXBElement<AddressType> createShippingAddress(AddressType value) {        returnnewJAXBElement<AddressType>(_ShippingAddress_QNAME, AddressType.class, null, value);    }} | 
Пакет-инфо
Класс package-info используется для определения сопоставления пространства имен (см. JAXB & Namespaces ).
| 1 2 3 4 | packageorg.example.customer;importjavax.xml.bind.annotation.*; | 
Unmarshal Operation
Теперь мы рассмотрим влияние типа корневого элемента при демаршаллинге XML.
customer.xml
Ниже приведен пример XML-документа с клиентом в качестве корневого элемента. Помните, что элемент customer имел анонимный сложный тип.
| 1 2 3 4 5 6 7 8 9 | <?xmlversion="1.0"encoding="UTF-8"?>    <billing-address>        <street>1 Any Street</street>    </billing-address>    <shipping-address>        <street>2 Another Road</street>    </shipping-address></customer> | 
shipping.xml
Вот пример XML-документа с адресом доставки в качестве корневого элемента. Элемент shipping-address имеет названный комплексный тип.
| 1 2 3 4 | <?xmlversion="1.0"encoding="UTF-8"?>    <street>2 Another Road</street></shipping-address> | 
  Демарш Демо 
 
  При демаршировании XML, который соответствует классу, аннотированному @XmlRootElement, вы получаете экземпляр объекта домена.  Но при демаршировании XML, который соответствует классу, аннотированному @XmlElementDecl, вы получаете объект домена, обернутый в экземпляр J AXBElement .  В этом примере вам может понадобиться использовать QName из JAXBElement, чтобы определить, не выписали ли вы адрес для выставления счета или адрес доставки. 
| 01 02 03 04 05 06 07 08 09 10 11 12 13 14 15 16 17 18 19 20 21 22 | packageorg.example.customer;importjava.io.File;importjavax.xml.bind.*;publicclassUnmarshalDemo {    publicstaticvoidmain(String[] args) throwsException {        JAXBContext jc = JAXBContext.newInstance("org.example.customer");        Unmarshaller unmarshaller = jc.createUnmarshaller();        // Unmarshal Customer        File customerXML = newFile("src/org/example/customer/customer.xml");        Customer customer = (Customer) unmarshaller.unmarshal(customerXML);        // Unmarshal Shipping Address        File shippingXML = newFile("src/org/example/customer/shipping.xml");        JAXBElement<AddressType> je = (JAXBElement<AddressType>) unmarshaller.unmarshal(shippingXML);        AddressType shipping = je.getValue();    }} | 
  Демо Unmarshal — JAXBIntrospector 
 
  Если вы не хотите иметь дело с запоминанием, будет ли результатом операции unmarshal будет объект домена или JAXBElement , то вы можете использовать метод JAXBIntrospector.getValue (Object), чтобы всегда получать объект домена. 
| 01 02 03 04 05 06 07 08 09 10 11 12 13 14 15 16 17 18 19 20 21 22 23 | packageorg.example.customer;importjava.io.File;importjavax.xml.bind.*;publicclassJAXBIntrospectorDemo {    publicstaticvoidmain(String[] args) throwsException {        JAXBContext jc = JAXBContext.newInstance("org.example.customer");        Unmarshaller unmarshaller = jc.createUnmarshaller();        // Unmarshal Customer        File customerXML = newFile("src/org/example/customer/customer.xml");        Customer customer = (Customer) JAXBIntrospector.getValue(unmarshaller                .unmarshal(customerXML));        // Unmarshal Shipping Address        File shippingXML = newFile("src/org/example/customer/shipping.xml");        AddressType shipping = (AddressType) JAXBIntrospector                .getValue(unmarshaller.unmarshal(shippingXML));    }} | 
  Маршал Операция 
 
  Вы можете напрямую упорядочить объект, аннотированный @XmlRootElement, в XML.  Классы, соответствующие аннотациям @XmlElementDecl, должны быть сначала помещены в экземпляр JAXBElement .  Фабричный метод, который вы аннотировали @XmlElementDecl, — это самый простой способ сделать это.  Метод фабрики находится в классе ObjectFactory, если вы сгенерировали свою модель из схемы XML. 
| 01 02 03 04 05 06 07 08 09 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 | packageorg.example.customer;importjavax.xml.bind.*;publicclassMarshalDemo {    publicstaticvoidmain(String[] args) throwsException {        JAXBContext jc = JAXBContext.newInstance("org.example.customer");        Marshaller marshaller = jc.createMarshaller();        marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true);        // Create Domain Objects        AddressType billingAddress = newAddressType();        billingAddress.setStreet("1 Any Street");        Customer customer = newCustomer();        customer.setBillingAddress(billingAddress);        // Marshal Customer        marshaller.marshal(customer, System.out);        // Marshal Billing Address        ObjectFactory objectFactory = newObjectFactory();        JAXBElement<AddressType> je =  objectFactory.createBillingAddress(billingAddress);        marshaller.marshal(je, System.out);    }} | 
Выход
Ниже приведен результат запуска демонстрационного кода.
| 01 02 03 04 05 06 07 08 09 10 | <?xmlversion="1.0"encoding="UTF-8"standalone="yes"?>    <billing-address>        <street>1 Any Street</street>    </billing-address></customer><?xmlversion="1.0"encoding="UTF-8"standalone="yes"?>    <street>1 Any Street</street></billing-address> | 
Ссылка: JAXB и Root Elements от нашего партнера JCG Блэза Дафана в блоге Java XML & JSON Binding .