Jibx 处理XML
Jibx 处理XML前面有介绍过json-lib这个框架,在线博文:http://www.cnblogs.com/hoojo/archive/2011/04/21/2023805.html 以及Jackson这个框架,在线博文:http://www.cnblogs.com/hoojo/archive/2011/04/22/2024628.html 它们都可以完成Java对象到XML的转换,但是还不是那么的完善。 还有XStream对JSON及XML的支持,它可以对JSON或XML的完美转换。在线博文: http://www.cnblogs.com/hoojo/archive/2011/04/22/2025197.html 以及介绍Castor来完成Java对象到xml的相互转换。在线博文:http://www.cnblogs.com/hoojo/archive/2011/04/25/2026819.html Jaxb2完成xml的转换,在线博文:http://www.cnblogs.com/hoojo/archive/2011/04/26/2029011.html Jibx对Java对象的转换相对要负责些,它不仅需要配置xml还且还要生成相应的jar文件,已经xsd文件。下面我们就来慢慢看看Jibx转换Java到XML是如何完成的。 一、准备工作 1、 准备资源 a) 官方示例:http://jibx.sourceforge.net/fromcode/bindgen-examples.html http://www.java2s.com/Open-Source/Java/XML/JiBX/tutorial/Catalogtutorial.htm b) Jar下载:http://sourceforge.net/projects/jibx/files/ c) 依赖jar包如下: 2、 程序准备代码 package com.hoo.test;
import java.io.IOException; import java.io.StringReader; import java.io.StringWriter; import java.util.ArrayList; import java.util.HashMap; import java.util.List; import org.jibx.runtime.BindingDirectory; import org.jibx.runtime.IBindingFactory; import org.jibx.runtime.IMarshallingContext; import org.jibx.runtime.IUnmarshallingContext; import org.jibx.runtime.JiBXException; import org.junit.After; import org.junit.Before; import org.junit.Test; import com.hoo.entity.Account; import com.hoo.entity.AccountArray; import com.hoo.entity.Birthday; import com.hoo.entity.ListBean; import com.hoo.entity.MapBean; /** * <b>function:</b> Jibx转换Java到XML * @author hoojo * @createDate 2011-4-25 下午06:47:33 * @file JibxTest.java * @package com.hoo.test * @project WebHttpUtils * @blog http://blog.csdn.net/IBM_hoojo * @email hoojo_@126.com * @version 1.0 */ public class JibxTest {
private IBindingFactory factory = null;
private StringWriter writer = null; private StringReader reader = null; private Account bean = null; @Before void init() { bean = new Account();
bean.setAddress("北京");
bean.setEmail("email");
bean.setId(1); bean.setName("jack");
Birthday day = new Birthday();
day.setBirthday("2010-11-22");
bean.setBirthday(day); try {
factory = BindingDirectory.getFactory(Account.class);
} catch (JiBXException e) {
e.printStackTrace(); } } @After void destory() { bean = null; if (writer != null) {
writer.flush(); writer.close(); } if (reader != null) { reader.close(); } catch (IOException e) { System.gc(); } void fail(Object o) { System.out.println(o); void failRed(Object o) { System.err.println(o); } IBindingFactory是一个工厂接口,通过BindingDirectory的getFactory工厂方法可以获得某个对象。然后通过这个工程可以获得转换xml文档的上下文。 二、转换Java到XML、转换XML到Java 1、 转换JavaEntity对象 a) 首先看看Account、Birthday的代码 package com.hoo.entity;
class Account { private int id;
private String name; private String email; private String address; private Birthday birthday; //getter、setter @Override public String toString() { return this.id + "#" + this.name + this.email + this.address + this.birthday; } Birthday class Birthday {
private String birthday; public Birthday(String birthday) { super(); this.birthday = birthday; //getter、setter public Birthday() {} } b) 程序代码 @Test
void bean2XML() { writer = new StringWriter();
// marshal 编组 IMarshallingContext mctx = factory.createMarshallingContext(); mctx.setIndent(2); mctx.marshalDocument(bean,"UTF-8",null,writer);
fail(writer); reader = new StringReader(writer.toString());
//unmarshal 解组 IUnmarshallingContext uctx = factory.createUnmarshallingContext(); Account acc = (Account) uctx.unmarshalDocument(reader,null); fail(acc); } catch (Exception e) {
e.printStackTrace(); } 这样还不够,复杂的东西还在后面。Jibx转换XML文档还要经过一系列复杂的程序。 c) 首先,要写bind.xml和schema。不过还好,官方有提高工具类可以用。 org.jibx.binding.generator.BindGen或org.jibx.binding.BindingGenerator这两个类都可以,用法如下: 首先用dos进入当前工程目录,然后执行命令:E:StudyWebHttpUtils>java -cp bin;lib/jibx-tools.jar;lib/log4j-1.2.16.jar org.jibx.binding.generator.BindGen -b bind.xml com.hoo.entity.Account 上面的java 是运行某个程序 –cp是依赖的classpath路径的jar、zip等文件,-b 是输出文件名称,是BindGen类的参数。这样会在当前工程目录中生成bind.xml和entity.xsd文件。先看看这2个文件 bind.xml <?xml version="1.0" encoding="UTF-8"?>
<binding value-style="attribute"> <mapping class="com.hoo.entity.Account" name="account"<value name="id" field="id"/<value style="element" name="name" field="name" usage="optional"/style="element" name="email" field="email" usage="optional"/style="element" name="address" field="address" usage="optional"/<structure field="birthday" usage="optional" name="birthday" style="element" name="birthday" field="birthday" usage="optional"/</structure</mapping</binding> entity.xsd文件 <xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:tns="http://hoo.com/entity"
elementFormDefault="qualified" targetNamespace="http://hoo.com/entity">
<xs:element type="tns:account" name="account"/<xs:complexType name="account"<xs:sequence<xs:element type="xs:string" name="name" minOccurs="0"/<xs:element type="xs:string" name="email" minOccurs="0"/<xs:element type="xs:string" name="address" minOccurs="0"/<xs:element name="birthday" minOccurs="0"<xs:complexType <xs:element type="xs:string" name="birthday" minOccurs="0"/</xs:sequence</xs:complexType</xs:element<xs:attribute type="xs:int" use="required" name="id"/</xs:schema> 上面最重要的就是bind.xml文件了,下面编译的时候需要这个文件。Xsd文件可以根据这个文件的内容生成Java的Entity类代码。 执行完命令后,没有错误就可以运行下面一段命令了。运行命令: E:StudyWebHttpUtils>java -cp bin;lib/jibx-bind.jar org.jibx.binding.Compile -v bind.xml -v是绑定文件的名称 运行后,有如下结果: d) 然后你就可以运行上面的Java的Junit测试程序了,运行后结果如下: <account xmlns="http://hoo.com/entity" id="1">
<name>jack</name<email>email</email<address>北京</<birthday>2010-11-22</birthday</account1#jack#email#北京#2010-11-22 你还可以用命令来查看某个已经生成bind、schema文件的信息,如: java -cp bin;lib/jibx-run.jar org.jibx.runtime.PrintInfo -c com.hoo.entity.Account 结果如下: e) 注意,有时候会出现异常信息,如:java.lang.NoSuchFieldException: JiBX_bindingXXXX就要重复下面的命令就可以了。 java -cp bin;lib/jibx-bind.jar org.jibx.binding.Compile -v bind.xml 2、 转换带List集合属性的JavaBean a) 程序代码 void listBean2XML() {
ListBean listBean = new ListBean();
List<Account> list = new ArrayList<Account>();
list.add(bean); new Account(); "china"); "tom@125.com"); bean.setId(2); "tom"); new Birthday( list.add(bean);
listBean.setList(list); new StringWriter(); factory = BindingDirectory.getFactory(ListBean. mctx.marshalDocument(listBean,monospace; direction:ltr; font-size:10pt; overflow:visible"> listBean = (ListBean) uctx.unmarshalDocument(reader,monospace; direction:ltr; font-size:10pt; overflow:visible"> fail(listBean.getList().get(0));
fail(listBean.getList().get(1)); } b) ListBean代码 import java.util.List;
class ListBean { private String name; private List list; } c) 生成bind.xml 执行dos命令: java -cp bin;lib/jibx-tools.jar;lib/log4j-1.2.16.jar org.jibx.binding.BindingGenerator -f bind.xml com.hoo.entity.ListBean 输出: d) 执行完后会生产bind.xml Bind文件 .ListBean" name="list-bean"<collection field="list" usage="optional" factory="org.jibx.runtime.Utility.arrayListFactory"/>
e) 运行Compile工具类 在运行前,一定要将最先前运行的Account那个类的bind.xml文件的内容加入到现在这个bind.xml中,因为ListBean依赖了Account这个类。 命令如下: java -cp bin;lib/jibx-bind.jar org.jibx.binding.Compile -v bind.xml 运行后你可以看到最后出现这个 f) 运行Test程序,结果如下: <list-bean<account id="1"<account id="2">tom>tom@125.com>china</list-bean1#jack#email#北京#2010-11-22
2#tom#tom@125.com#china#2010-11-22
3、 转换Java对象数组 a) Test程序 * <b>function:</b>转换对象数组
* @createDate 2011-4-26 下午05:32:03 @Test void arrayBean2XML() { try { Account[] acc = new Account[2];
acc[0] = bean; "tom"); bean.setId(223); acc[1] = bean; AccountArray array = new AccountArray();
array.setAccounts(acc); factory = BindingDirectory.getFactory(AccountArray. mctx.marshalDocument(array,monospace; direction:ltr; font-size:10pt; overflow:visible"> array = (AccountArray) uctx.unmarshalDocument(reader,monospace; direction:ltr; font-size:10pt; overflow:visible"> fail(array.getAccounts()[0]);
fail(array.getAccounts()[1]); } b) AccountArray代码 class AccountArray {
private Account[] accounts; int size; int getSize() { size = accounts.length; return size; void setSize(int size) {
this.size = size; public Account[] getAccounts() { return accounts; void setAccounts(Account[] accounts) { this.accounts = accounts; } c) 运行命令生成bind.xml文件 命令如下: java -cp bin;lib/jibx-tools.jar;lib/log4j-1.2.16.jar org.jibx.binding.BindingGenerator -f bind.xml com.hoo.entity.Account com.hoo.entity.AccountArray 因为AccountArray依赖Account,所以后面带2个类 d) 运行Compile命令 java -cp bin;lib/jibx-bind.jar org.jibx.binding.Compile -v bind.xml e) 执行完后,就可以运行Test程序了,结果如下 <account-array size="0"<account id="223"</account-array1#jack#email#北京#2010-11-22
223#tom#null#null#null 4、 转换带Map结合的JavaEntity对象 a) Test代码 * <b>function:</b>转换Map集合
* @createDate 2011-4-26 下午05:40:34 void mapBean2XML() { MapBean mapBean = new MapBean();
HashMap<String,Account> map = new HashMap<String,Account>();
map.put("No1",bean);
"No2",monospace; direction:ltr; font-size:10pt; overflow:visible"> mapBean.setMap(map); factory = BindingDirectory.getFactory(MapBean.// marshal 编组
IMarshallingContext mctx = factory.createMarshallingContext(); mctx.setIndent(2); mctx.marshalDocument(mapBean,writer); fail(writer); new StringReader(writer.toString()); //unmarshal 解组 IUnmarshallingContext uctx = factory.createUnmarshallingContext(); mapBean = (MapBean) uctx.unmarshalDocument(reader,null); fail(mapBean.getMap()); fail(mapBean.getMap().get("No1"));
"No2")); } b) MapBean代码 class MapBean {
private HashMap<String,Account> map; public HashMap<String,Account> getMap() { return map; void setMap(HashMap<String,Account> map) { this.map = map; } c) 生成bind.xml,命令如下 E:StudyWebHttpUtils>java -cp bin;lib/jibx-tools.jar;lib/log4j-1.2.16.jar org.jibx.binding.BindingGenerator -f bind.xml com.hoo.entity.Account com.hoo.entity.MapBean 运行后,会生产bind.xml;修改bind.xml内容如下: <value name="id" field="id" /style="element" name="name" field="name" usage="optional" /style="element" name="email" field="email" usage="optional" /address" usage="optional" /style="element" name="birthday" field="birthday" usage="optional" /.MapBean" name="map-bean"<structure field="map" usage="optional" name="map"
marshaller="com.util.HashMapper" unmarshaller="com.HashMapper"> 注意上面的MapBean的structure元素的内容是经过修改的。一定要带上marshaller或unmarshaller,不然无法转换HashMap的。 d) HashMapper代码 package com.hoo.util;
import java.util.Iterator; import java.util.Map; import org.jibx.runtime.IAliasable; import org.jibx.runtime.IMarshallable; import org.jibx.runtime.IMarshaller; import org.jibx.runtime.IUnmarshaller; import org.jibx.runtime.IUnmarshallingContext; import org.jibx.runtime.JiBXException; import org.jibx.runtime.impl.MarshallingContext; import org.jibx.runtime.impl.UnmarshallingContext; /** * <b>function:</b>http://www.java2s.com/Open-Source/Java/XML/JiBX/tutorial/example21/HashMapper.java.htm * @file HashMapper.java * @package com.hoo.util * @project WebHttpUtils * @blog http://blog.csdn.net/IBM_hoojo * @email hoojo_@126.com * @version 1.0 */ class HashMapper implements IMarshaller,IUnmarshaller,IAliasable
{ static final String SIZE_ATTRIBUTE_NAME = "size"; final String ENTRY_ELEMENT_NAME = "entry";
final String KEY_ATTRIBUTE_NAME = "key";
final int DEFAULT_SIZE = 10;
private String m_uri; int m_index; private String m_name; public HashMapper() { m_uri = null; m_index = 0; m_name = "hashmap";
public HashMapper(String uri,255)">int index,String name) { m_uri = uri; m_index = index; m_name = name; /* (non-Javadoc) * @see org.jibx.runtime.IMarshaller#isExtension(int) */ boolean isExtension(int index) {
return false; * @see org.jibx.runtime.IMarshaller#marshal(java.lang.Object, * org.jibx.runtime.IMarshallingContext) */ void marshal(Object obj,IMarshallingContext ictx) throws JiBXException { // make sure the parameters are as expected if (!(obj instanceof HashMap)) {
throw new JiBXException("Invalid object type for marshaller"); else if (!(ictx instanceof MarshallingContext)) { else { // start by generating start tag for container MarshallingContext ctx = (MarshallingContext)ictx; HashMap map = (HashMap)obj; ctx.startTagAttributes(m_index,m_name). attribute(m_index,SIZE_ATTRIBUTE_NAME,map.size()). closeStartContent(); // loop through all entries in hashmap Iterator iter = map.entrySet().iterator(); while (iter.hasNext()) { Map.Entry entry = (Map.Entry)iter.next(); ctx.startTagAttributes(m_index,ENTRY_ELEMENT_NAME); if (entry.getKey() != null) {
ctx.attribute(m_index,KEY_ATTRIBUTE_NAME, entry.getKey().toString()); } ctx.closeStartContent(); if (entry.getValue() instanceof IMarshallable) {
((IMarshallable)entry.getValue()).marshal(ctx); ctx.endTag(m_index,monospace; direction:ltr; font-size:10pt; overflow:visible"> } "Mapped value is not marshallable");
} // finish with end tag for container element ctx.endTag(m_index,m_name); } /* (non-Javadoc) * @see org.jibx.runtime.IUnmarshaller#isPresent(org.jibx.runtime.IUnmarshallingContext) boolean isPresent(IUnmarshallingContext ctx) throws JiBXException {
return ctx.isAt(m_uri,m_name); * @see org.jibx.runtime.IUnmarshaller#unmarshal(java.lang.Object, * org.jibx.runtime.IUnmarshallingContext) public Object unmarshal(Object obj,IUnmarshallingContext ictx) // make sure we're at the appropriate start tag UnmarshallingContext ctx = (UnmarshallingContext)ictx; if (!ctx.isAt(m_uri,m_name)) { ctx.throwStartTagNameError(m_uri,0)">// create new hashmap if needed int size = ctx.attributeInt(m_uri,DEFAULT_SIZE); HashMap map = (HashMap)obj; if (map == null) { map = new HashMap(size);
// process all entries present in document ctx.parsePastStartTag(m_uri,255)">while (ctx.isAt(m_uri,ENTRY_ELEMENT_NAME)) { Object key = ctx.attributeText(m_uri,monospace; direction:ltr; font-size:10pt; overflow:visible"> ctx.parsePastStartTag(m_uri,monospace; direction:ltr; font-size:10pt; overflow:visible"> Object value = ctx.unmarshalElement(); map.put(key,value); ctx.parsePastEndTag(m_uri,ENTRY_ELEMENT_NAME); ctx.parsePastEndTag(m_uri,255)">return map; boolean isExtension(String arg0) { return false; } e) 然后运行Compile命令 E:StudyWebHttpUtils>java -cp bin;lib/jibx-bind.jar org.jibx.binding.Compile -v bind.xml f) 结果如下 map-beanmap size="2"<entry key="No2"</entry<entry key="No1"map{No2=2#tom#tom@125.com#china#2010-11-22,No1=1#jack#email#北京#2010-11-22}
.com#china#2010-11-22 版权所有,转载请注明出处 本文出自: 版权所有,欢迎转载,转载请注明出处,谢谢
赞
Top↑
收藏
关注
评论
分类:
JavaEE,JavaSE,Others,JSON&XML
标签:
XML
(编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |