XML模式
下面的XML模式包含三個根元素: customer , billing-address和shipping-address 。 customer元素具有匿名的復雜類型,而billing-address和shipping-address具有相同的命名類型( address-type )。
<?xml version="1.0" encoding="UTF-8"?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" targetNamespace="http://www.example.org/customer" xmlns="http://www.example.org/customer" elementFormDefault="qualified"><xs:element name="customer"><xs:complexType><xs:sequence><xs:element ref="billing-address"/><xs:element ref="shipping-address"/></xs:sequence></xs:complexType></xs:element><xs:complexType name="address-type"><xs:sequence><xs:element name="street" type="xs:string"/></xs:sequence></xs:complexType><xs:element name="billing-address" type="address-type"/><xs:element name="shipping-address" type="address-type"/></xs:schema>
生成模型
下面是從XML模式生成的JAXB模型。 將JAXB批注添加到現有Java模型時,將應用相同的概念。
顧客
JAXB域類對應于復雜類型。 由于customer元素具有匿名復雜類型,因此Customer類具有@XmlRootElement批注。 這是因為只有一個XML元素可以與匿名類型相關聯。
package org.example.customer;import javax.xml.bind.annotation.*;@XmlAccessorType(XmlAccessType.FIELD)
@XmlType(name = "", propOrder = {"billingAddress","shippingAddress"})
@XmlRootElement(name = "customer")
public class Customer {@XmlElement(name = "billing-address", required = true)protected AddressType billingAddress;@XmlElement(name = "shipping-address", required = true)protected AddressType shippingAddress;public AddressType getBillingAddress() {return billingAddress;}public void setBillingAddress(AddressType value) {this.billingAddress = value;}public AddressType getShippingAddress() {return shippingAddress;}public void setShippingAddress(AddressType value) {this.shippingAddress = value;}}
地址類型
同樣,因為JAXB模型類對應于復雜類型,所以會為地址類型的復雜類型生成一個類。 由于此命名的復雜類型可能存在多個根級別元素,因此不會使用@XmlRootElement對其進行注釋。
package org.example.customer;import javax.xml.bind.annotation.*;@XmlAccessorType(XmlAccessType.FIELD)
@XmlType(name = "address-type", propOrder = {"street"})
public class AddressType {@XmlElement(required = true)protected String street;public String getStreet() {return street;}public void setStreet(String value) {this.street = value;}}
對象工廠
@XmlElementDecl批注用于表示與命名的復雜類型相對應的根元素。 它放在@XmlRegistry注釋的類中的工廠方法上(從XML模式生成時,該類始終稱為ObjectFactory )。 factory方法返回包裝在JAXBElement實例中的域對象。 JAXBElement具有一個QName ,它表示元素名稱和名稱空間URI。
package org.example.customer;import javax.xml.bind.JAXBElement;
import javax.xml.bind.annotation.*;
import javax.xml.namespace.QName;@XmlRegistry
public class ObjectFactory {private final static QName _BillingAddress_QNAME = new QName("http://www.example.org/customer", "billing-address");private final static QName _ShippingAddress_QNAME = new QName("http://www.example.org/customer", "shipping-address");public ObjectFactory() {}public Customer createCustomer() {return new Customer();}public AddressType createAddressType() {return new AddressType();}@XmlElementDecl(namespace = "http://www.example.org/customer", name = "billing-address")public JAXBElement<AddressType> createBillingAddress(AddressType value) {return new JAXBElement<AddressType>(_BillingAddress_QNAME, AddressType.class, null, value);}@XmlElementDecl(namespace = "http://www.example.org/customer", name = "shipping-address")public JAXBElement<AddressType> createShippingAddress(AddressType value) {return new JAXBElement<AddressType>(_ShippingAddress_QNAME, AddressType.class, null, value);}}
包裝信息
package-info類用于指定名稱空間映射(請參見JAXB和Namespaces )。
@XmlSchema(namespace = "http://www.example.org/customer", elementFormDefault = XmlNsForm.QUALIFIED)
package org.example.customer;import javax.xml.bind.annotation.*;
非海警行動
現在我們來看一下解組XML時根元素類型的影響。
customer.xml
下面是一個示例XML文檔,其中有customer作為根元素。 請記住, customer元素具有匿名的復雜類型。
<?xml version="1.0" encoding="UTF-8"?>
<customer xmlns="http://www.example.org/customer"><billing-address><street>1 Any Street</street></billing-address><shipping-address><street>2 Another Road</street></shipping-address>
</customer>
shipping.xml
這是一個示例XML文檔,其中shipping-address作為根元素。 送貨地址元素具有命名的復雜類型。
<?xml version="1.0" encoding="UTF-8"?>
<shipping-address xmlns="http://www.example.org/customer"><street>2 Another Road</street>
</shipping-address>
解組演示
?
當解組與用@XmlRootElement注釋的類相對應的XML時,您將獲得域對象的實例。 但是,當解組與用@XmlElementDecl注釋的類相對應的XML時,您將得到包裝在J AXBElement實例中的域對象。 在此示例中,您可能需要使用JAXBElement中的QName來確定是否對帳單地址或收貨地址進行了編組。
package org.example.customer;import java.io.File;
import javax.xml.bind.*;public class UnmarshalDemo {public static void main(String[] args) throws Exception {JAXBContext jc = JAXBContext.newInstance("org.example.customer");Unmarshaller unmarshaller = jc.createUnmarshaller();// Unmarshal CustomerFile customerXML = new File("src/org/example/customer/customer.xml");Customer customer = (Customer) unmarshaller.unmarshal(customerXML);// Unmarshal Shipping AddressFile shippingXML = new File("src/org/example/customer/shipping.xml");JAXBElement<AddressType> je = (JAXBElement<AddressType>) unmarshaller.unmarshal(shippingXML);AddressType shipping = je.getValue();}}
Unmarshal演示– JAXBIntrospector
?
如果您不想記住解組操作的結果是域對象還是JAXBElement ,則可以使用JAXBIntrospector.getValue(Object)方法始終獲取域對象。
package org.example.customer;import java.io.File;
import javax.xml.bind.*;public class JAXBIntrospectorDemo {public static void main(String[] args) throws Exception {JAXBContext jc = JAXBContext.newInstance("org.example.customer");Unmarshaller unmarshaller = jc.createUnmarshaller();// Unmarshal CustomerFile customerXML = new File("src/org/example/customer/customer.xml");Customer customer = (Customer) JAXBIntrospector.getValue(unmarshaller.unmarshal(customerXML));// Unmarshal Shipping AddressFile shippingXML = new File("src/org/example/customer/shipping.xml");AddressType shipping = (AddressType) JAXBIntrospector.getValue(unmarshaller.unmarshal(shippingXML));}}
元帥行動
?
您可以直接將帶有@XmlRootElement注釋的對象編組為XML。 與@XmlElementDecl批注對應的類必須首先包裝在JAXBElement的實例中。 用@XmlElementDecl注釋的工廠方法是最簡單的方法。 如果您是從XML模式生成模型的,則工廠方法位于ObjectFactory類中。
package org.example.customer;import javax.xml.bind.*;public class MarshalDemo {public static void main(String[] args) throws Exception {JAXBContext jc = JAXBContext.newInstance("org.example.customer");Marshaller marshaller = jc.createMarshaller();marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true);// Create Domain ObjectsAddressType billingAddress = new AddressType();billingAddress.setStreet("1 Any Street");Customer customer = new Customer();customer.setBillingAddress(billingAddress);// Marshal Customermarshaller.marshal(customer, System.out);// Marshal Billing AddressObjectFactory objectFactory = new ObjectFactory();JAXBElement<AddressType> je = objectFactory.createBillingAddress(billingAddress);marshaller.marshal(je, System.out);}}
輸出量
以下是運行演示代碼的輸出。
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<customer xmlns="http://www.example.org/customer"><billing-address><street>1 Any Street</street></billing-address>
</customer>
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<billing-address xmlns="http://www.example.org/customer"><street>1 Any Street</street>
</billing-address>
參考: Java XML和JSON綁定博客中的JCG合作伙伴 Blaise Doughan的JAXB和Root Elements 。
翻譯自: https://www.javacodegeeks.com/2012/08/jaxb-and-root-elements.html