读取xml对于应用软件来说是一个必不可少的工作,当然现在的jdk也提供了很好的处理xml方式,读写xml的库也挺多,包括有名的dom4j,不管使用任何的代码库,对于xml只是一个解析工作而已,不能马上绑定到java 对象。对于对象,每次都需要set 或者get相应的属性,当然也可以使用map 来保存xml配置。 于是,一种新的处理方式用于对象和xml之间的映射就变得非常需要,还好sun提供了jaxb,一种很方便的方式来处理java对象和xml内容。下面通过一个实例来体会一下。 看一下如下的xml <?xml version="1.0"?> <customer id="No1"> <name>Alice Smith</name> <address> <street>123 Maple Street</street> <city>Cambridge</city> <zip>12345</zip> </address> </customer> 别忘了生成相应的xsd,或者dtd文件,这是主要的配置: xsd: <xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema">
<xs:complexType name="Customer"> <xs:sequence> <xs:element name="address" type="Address"/> <xs:element name="name" type="xs:string"/> </xs:sequence> <xs:attribute name="id" type="xs:string"/> </xs:complexType>
<xs:complexType name="Address"> <xs:sequence> <xs:element name="street" type="xs:string"/> <xs:element name="city" type="xs:string"/> <xs:element name="zip" type="ZipCodeType"/> </xs:sequence> </xs:complexType>
<xs:simpleType name="ZipCodeType"> <xs:restriction base="xs:integer"> <xs:minInclusive value="10000"/> <xs:maxInclusive value="99999"/> </xs:restriction> </xs:simpleType> <xs:element name="customer" type="Customer"/> <xs:element name="address" type="Address"/> </xs:schema> 需要映射两个java对象,CustomerBo和AddressBo java 对象可以通过xjc来生成。 或者自己定义(但需要增加相应的java注释,如@XmlAccessorType,@XmlType,这是给引擎使用的) 所以一般通过xjd自动生成 @XmlAccessorType(AccessType.FIELD) @XmlType(name = "Customer", propOrder = { "address", "customerName" }) public class CustomerBo { protected Address address; @XmlElement(name = "name") protected String customerName; @XmlAttribute protected String id; public Address getAddress() { return address; } public String getCustomerName() { return customerName; } public String getId() { return id; } public void setAddress(Address value) { this.address = value; } public void setCustomerName(String value) { this.customerName = value; } public void setId(String value) { this.id = value; } } public class Address { protected String street; protected String city; @XmlElement(name = "zip") protected BigInteger zipCode; public String getStreet() { return street; } public void setStreet(String value) { this.street = value; } public String getCity() { return city; } public void setCity(String value) { this.city = value; } public BigInteger getZipCode() { return zipCode; } public void setZipCode(BigInteger value) { this.zipCode = value; } } 定义jxb绑定文件: <jxb:bindings version="1.0" xmlns:jxb="http://java.sun.com/xml/ns/jaxb" xmlns:xs="http://www.w3.org/2001/XMLSchema"> <jxb:bindings schemaLocation="customer.xsd" node="/xs:schema">
<jxb:globalBindings fixedAttributeAsConstantProperty="false" collectionType="java.util.Vector" typesafeEnumBase="xs:NCName" choiceContentProperty="false" typesafeEnumMemberName="generateError" enableFailFastCheck="false" generateIsSetMethod="false" underscoreBinding="asCharInWord"/> <jxb:schemaBindings> <jxb:package name="mycompany.demo"> <jxb:javadoc><![CDATA[<body>Package level documentation for generated package mycompany.demo.</body>]]> </jxb:javadoc> </jxb:package> <jxb:nameXmlTransform> <jxb:elementName suffix="Element"/> </jxb:nameXmlTransform> </jxb:schemaBindings> //需要绑定的元素 <jxb:bindings node="//xs:complexType[@name='Customer']"> //绑定的类 <jxb:class name="CustomerBo"> <jxb:javadoc>A <b>todo..</jxb:javadoc> </jxb:class> <jxb:bindings node=".//xs:element[@name='name']"> //绑定的属性 <jxb:property name="customerName"/> </jxb:bindings> </jxb:bindings>
<jxb:bindings node="//xs:complexType[@name='Address']"> <jxb:class name="AddressBo"> <jxb:javadoc><![CDATA[First line of documentation for a <b>Address</b>.]]></jxb:javadoc> </jxb:class> <jxb:bindings node=".//xs:element[@name='zip']"> <jxb:property name="zipCode"/> </jxb:bindings> </jxb:bindings>
</jxb:bindings> </jxb:bindings>
看着比较复杂,其实挺好理解,当然可以不需要这个绑定文件,也可以绑定相应的java 类,但需要元素名称和类名称完全一致,而且属性也要一致。 看一下jaxb是如何来读入xml的: //主要的环境类,主要读取ObjectFactory这个类,这是由xjc生成的。 JAXBContext jc = JAXBContext.newInstance("mycompany.demo"); Unmarshaller u = jc.createUnmarshaller(); JAXBElement customerE = (JAXBElement) u.unmarshal(new FileInputStream( "customer.xml")); CustomerBo bo = (CustomerBo) customerE.getValue(); 就是这么简单 写入也比较简单: JAXBContext jc = JAXBContext.newInstance("mycompany.demo"); Marshaller marshaller=jc.createMarshaller(); marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, Boolean.TRUE); customerE.setValue(bo); marshaller.marshal( customerE,new FileOutputStream("test.xml"));
在webservices中jaxb的作用是明显的,当然也有不方便的地方,比如定义binding.jaxb文件时,如果没有工具支持,手工写,还是比较困难。 |