锁定老帖子 主题:从一个实例看jaxb的强大
该帖已经被评为良好帖
|
|
---|---|
作者 | 正文 |
发表时间:2006-11-11
于是,一种新的处理方式用于对象和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文件时,如果没有工具支持,手工写,还是比较困难。 声明:ITeye文章版权属于作者,受法律保护。没有作者书面许可不得转载。
推荐链接
|
|
返回顶楼 | |
发表时间:2006-11-13
看起来好麻烦啊!简单用途的话XStream就可以了
|
|
返回顶楼 | |
发表时间:2006-11-13
贴个xstream的:)
public class Customer { protected Address address; protected String name; protected String id; public String toString(){ return id+ " " + name + "@" + address; } } import java.math.BigInteger; public class Address { protected String street; protected String city; protected BigInteger zip; public String toString(){ return city+ " " + street + " " + zip; } } import java.io.InputStream; import com.thoughtworks.xstream.XStream; public class XStreamDataReader { public static void main(String[] args) { XStream xstream = new XStream(); xstream.alias("customer", Customer.class); xstream.alias("address", Address.class); xstream.useAttributeFor("id", String.class); InputStream in = XStreamDataReader.class.getResourceAsStream("data.xml"); Customer bo = (Customer)xstream.fromXML(in); System.out.println(bo); xstream.toXML(bo, new FileWriter("data1.xml"));//另存为... } } |
|
返回顶楼 | |
发表时间:2006-11-14
一直用JiBX,觉得很好用,只要xml文件配置一下就ok了
|
|
返回顶楼 | |
发表时间:2006-11-14
看了楼主的文章,受益了, 不过还是有两个问题
------------------------------- 需要映射两个java对象,CustomerBo和AddressBo java 对象可以通过xjc来生成。 或者自己定义(但需要增加相应的java注释,如@XmlAccessorType,@XmlType,这是给引擎使用的) 所以一般通过xjd自动生成 一个java对像要用两种工具生成吗,是什么工具,能不能告诉我全名啊,。 --------------------------------------- 别忘了生成相应的xsd,或者dtd文件, 这个东东要用什么东东成生, --------------------------------------- JAXBContext jc = JAXBContext.newInstance("mycompany.demo"); mycompany.demo是什么东东 |
|
返回顶楼 | |
发表时间:2006-11-14
xmx0632 写道 贴个xstream的:)
public class XStreamDateReader { InputStream in = XStreamDateReader.class.getResourceAsStream("data.xml"); 大哥,你手真快!。。。上面的DateReader应该是DataReader吧 |
|
返回顶楼 | |
发表时间:2006-11-14
以前自己写,后来用过apache的betwixt,感觉比这里说的jaxb简单的多。
|
|
返回顶楼 | |
发表时间:2006-11-14
以前自己写,后来用过apache的betwixt,感觉比这里说的jaxb简单的多。
|
|
返回顶楼 | |
发表时间:2006-11-14
不好意思,我这里FCKeditor出错,连发了2次
|
|
返回顶楼 | |
发表时间:2006-11-15
想不到有那么多人关注,我只是在学习jaxb当中,有几点需要说明一下:
jaxb,不只是一个单纯的工具库,感觉功能比较强大,需要和其他的jaxp相互协作。 jaxb关注的方面更广,能处理更为复杂的xml, 看一下以下代码就可以知道: 代码1,处理xpath JAXBXpath jaxbXpath = new JAXBXpath(doc, binder); (USAddress) jaxbXpath.evaluate("/purchaseOrder/shipTo"); 代码2,直接更新xml Binder<Node> binder=JAXBContext.createBinder() JAXBElement<Items.Item> itemE = binder.unmarshal( node, Items.Item.class); binder.Items.Item item = itemE.getValue(); item.setComment("qualifies for free shipping"); binder.updateXML(item); 当然为了处理复杂的xml,其复杂的配置也是不可少的。 xstream 我也了解过,不过大多数情况下我只是用来作为java Serializable 而使用。 对于处理一些比较简单的xml,xstream 是比较方便。 感觉两者的目的不太一致。有兴趣的可以去看看sun的jwsdp带的相关例子 |
|
返回顶楼 | |