Jibx 处理XML

前端之家收集整理的这篇文章主要介绍了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、 程序准备代码

  1. package com.hoo.test;
  1.  
  1. import java.io.IOException;
  1. import java.io.StringReader;
  1. import java.io.StringWriter;
  1. import java.util.ArrayList;
  1. import java.util.HashMap;
  1. import java.util.List;
  1. import org.jibx.runtime.BindingDirectory;
  1. import org.jibx.runtime.IBindingFactory;
  1. import org.jibx.runtime.IMarshallingContext;
  1. import org.jibx.runtime.IUnmarshallingContext;
  1. import org.jibx.runtime.JiBXException;
  1. import org.junit.After;
  1. import org.junit.Before;
  1. import org.junit.Test;
  1. import com.hoo.entity.Account;
  1. import com.hoo.entity.AccountArray;
  1. import com.hoo.entity.Birthday;
  1. import com.hoo.entity.ListBean;
  1. import com.hoo.entity.MapBean;
  1. /**
  1. * <b>function:</b> Jibx转换JavaXML
  1. * @author hoojo
  1. * @createDate 2011-4-25 下午06:47:33
  1. * @file JibxTest.java
  1. * @package com.hoo.test
  1. * @project WebHttpUtils
  1. * @blog http://blog.csdn.net/IBM_hoojo
  1. * @email hoojo_@126.com
  1. * @version 1.0
  1. */
  1. public class JibxTest {
  1. private IBindingFactory factory = null;
  1. private StringWriter writer = null;
  1. private StringReader reader = null;
  1. private Account bean = null;
  1. @Before
  1. void init() {
  1. bean = new Account();
  1. bean.setAddress("北京");
  1. bean.setEmail("email");
  1. bean.setId(1);
  1. bean.setName("jack");
  1. Birthday day = new Birthday();
  1. day.setBirthday("2010-11-22");
  1. bean.setBirthday(day);
  1. try {
  1. factory = BindingDirectory.getFactory(Account.class);
  1. } catch (JiBXException e) {
  1. e.printStackTrace();
  1. }
  1. }
  1. @After
  1. void destory() {
  1. bean = null;
  1. if (writer != null) {
  1. writer.flush();
  1. writer.close();
  1. }
  1. if (reader != null) {
  1. reader.close();
  1. }
  1. catch (IOException e) {
  1. System.gc();
  1. }
  1. void fail(Object o) {
  1. System.out.println(o);
  1. void failRed(Object o) {
  1. System.err.println(o);
  1. }

IBindingFactory是一个工厂接口,通过BindingDirectory的getFactory工厂方法可以获得某个对象。然后通过这个工程可以获得转换xml文档的上下文。

二、转换Java到XML、转换XML到Java

1、 转换JavaEntity对象

a) 首先看看Account、Birthday的代码

package com.hoo.entity;
  1. class Account {
  1. private int id;
  1. private String name;
  1. private String email;
  1. private String address;
  1. private Birthday birthday;
  1. //getter、setter
  1. @Override
  1. public String toString() {
  1. return this.id + "#" + this.name + this.email + this.address + this.birthday;
  1. }

Birthday

class Birthday {
  1. private String birthday;
  1. public Birthday(String birthday) {
  1. super();
  1. this.birthday = birthday;
  1. //getter、setter
  1. public Birthday() {}
  1. }

b) 程序代码

@Test
  1. void bean2XML() {
  1. writer = new StringWriter();
  1. // marshal 编组
  1. IMarshallingContext mctx = factory.createMarshallingContext();
  1. mctx.setIndent(2);
  1. mctx.marshalDocument(bean,"UTF-8",null,writer);
  1. fail(writer);
  1. reader = new StringReader(writer.toString());
  1. //unmarshal 解组
  1. IUnmarshallingContext uctx = factory.createUnmarshallingContext();
  1. Account acc = (Account) uctx.unmarshalDocument(reader,null);
  1. fail(acc);
  1. } catch (Exception e) {
  1. e.printStackTrace();
  1. }

这样还不够,复杂的东西还在后面。Jibx转换XML文档还要经过一系列复杂的程序。

c) 首先,要写bind.xml和schema。不过还好,官方有提高工具类可以用。

org.jibx.binding.generator.BindGen或org.jibx.binding.BindingGenerator这两个类都可以,用法如下:

首先用dos进入当前工程目录,然后执行命令:E:\Study\WebHttpUtils>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"?>
  1. <binding value-style="attribute">
  1. <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"
  1. elementFormDefault="qualified" targetNamespace="http://hoo.com/entity">
  1. <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:\Study\WebHttpUtils>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">
  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() {
  1. ListBean listBean = new ListBean();
  1. List<Account> list = new ArrayList<Account>();
  1. list.add(bean);
  1. new Account();
  1. "china");
  1. "tom@125.com");
  1. bean.setId(2);
  1. "tom");
  1. new Birthday( list.add(bean);
  1. listBean.setList(list);
  1. new StringWriter();
  1. 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));
  1. fail(listBean.getList().get(1));
  1. }

b) ListBean代码

import java.util.List;
  1. class ListBean {
  1. private String name;
  1. private List list;
  1. }

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
  1. 2#tom#tom@125.com#china#2010-11-22

3、 转换Java对象数组

a) Test程序

* <b>function:</b>转换对象数组
  1. * @createDate 2011-4-26 下午05:32:03
  1. @Test
  1. void arrayBean2XML() {
  1. try {
  1. Account[] acc = new Account[2];
  1. acc[0] = bean;
  1. "tom");
  1. bean.setId(223);
  1. acc[1] = bean;
  1. AccountArray array = new AccountArray();
  1. array.setAccounts(acc);
  1. 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]);
  1. fail(array.getAccounts()[1]);
  1. }

b) AccountArray代码

class AccountArray {
  1. private Account[] accounts;
  1. int size;
  1. int getSize() {
  1. size = accounts.length;
  1. return size;
  1. void setSize(int size) {
  1. this.size = size;
  1. public Account[] getAccounts() {
  1. return accounts;
  1. void setAccounts(Account[] accounts) {
  1. this.accounts = accounts;
  1. }

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
  1. 223#tom#null#null#null

4、 转换带Map结合的JavaEntity对象

a) Test代码

* <b>function:</b>转换Map集合
  1. * @createDate 2011-4-26 下午05:40:34
  1. void mapBean2XML() {
  1. MapBean mapBean = new MapBean();
  1. HashMap<String,Account> map = new HashMap<String,Account>();
  1. map.put("No1",bean);
  1. "No2",monospace; direction:ltr; font-size:10pt; overflow:visible"> mapBean.setMap(map);
  1. factory = BindingDirectory.getFactory(MapBean.// marshal 编组
  1. IMarshallingContext mctx = factory.createMarshallingContext();
  1. mctx.setIndent(2);
  1. mctx.marshalDocument(mapBean,writer);
  1. fail(writer);
  1. new StringReader(writer.toString());
  1. //unmarshal 解组
  1. IUnmarshallingContext uctx = factory.createUnmarshallingContext();
  1. mapBean = (MapBean) uctx.unmarshalDocument(reader,null);
  1. fail(mapBean.getMap());
  1. fail(mapBean.getMap().get("No1"));
  1. "No2"));
  1. }

b) MapBean代码

class MapBean {
  1. private HashMap<String,Account> map;
  1. public HashMap<String,Account> getMap() {
  1. return map;
  1. void setMap(HashMap<String,Account> map) {
  1. this.map = map;
  1. }

c) 生成bind.xml,命令如下

E:\Study\WebHttpUtils>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"
  1. marshaller="com.util.HashMapper" unmarshaller="com.HashMapper">

注意上面的MapBean的structure元素的内容是经过修改的。一定要带上marshaller或unmarshaller,不然无法转换HashMap的。

d) HashMapper代码

package com.hoo.util;
  1. import java.util.Iterator;
  1. import java.util.Map;
  1. import org.jibx.runtime.IAliasable;
  1. import org.jibx.runtime.IMarshallable;
  1. import org.jibx.runtime.IMarshaller;
  1. import org.jibx.runtime.IUnmarshaller;
  1. import org.jibx.runtime.IUnmarshallingContext;
  1. import org.jibx.runtime.JiBXException;
  1. import org.jibx.runtime.impl.MarshallingContext;
  1. import org.jibx.runtime.impl.UnmarshallingContext;
  1.  
  1. /**
  1. * <b>function:</b>http://www.java2s.com/Open-Source/Java/XML/JiBX/tutorial/example21/HashMapper.java.htm
  1. * @file HashMapper.java
  1. * @package com.hoo.util
  1. * @project WebHttpUtils
  1. * @blog http://blog.csdn.net/IBM_hoojo
  1. * @email hoojo_@126.com
  1. * @version 1.0
  1. */
  1. class HashMapper implements IMarshaller,IUnmarshaller,IAliasable
  1. {
  1. static final String SIZE_ATTRIBUTE_NAME = "size";
  1. final String ENTRY_ELEMENT_NAME = "entry";
  1. final String KEY_ATTRIBUTE_NAME = "key";
  1. final int DEFAULT_SIZE = 10;
  1. private String m_uri;
  1. int m_index;
  1. private String m_name;
  1. public HashMapper() {
  1. m_uri = null;
  1. m_index = 0;
  1. m_name = "hashmap";
  1. public HashMapper(String uri,255)">int index,String name) {
  1. m_uri = uri;
  1. m_index = index;
  1. m_name = name;
  1. /* (non-Javadoc)
  1. * @see org.jibx.runtime.IMarshaller#isExtension(int)
  1. */
  1. boolean isExtension(int index) {
  1. return false;
  1. * @see org.jibx.runtime.IMarshaller#marshal(java.lang.Object,
  1. * org.jibx.runtime.IMarshallingContext)
  1. */
  1. void marshal(Object obj,IMarshallingContext ictx)
  1. throws JiBXException {
  1. // make sure the parameters are as expected
  1. if (!(obj instanceof HashMap)) {
  1. throw new JiBXException("Invalid object type for marshaller");
  1. else if (!(ictx instanceof MarshallingContext)) {
  1. else {
  1. // start by generating start tag for container
  1. MarshallingContext ctx = (MarshallingContext)ictx;
  1. HashMap map = (HashMap)obj;
  1. ctx.startTagAttributes(m_index,m_name).
  1. attribute(m_index,SIZE_ATTRIBUTE_NAME,map.size()).
  1. closeStartContent();
  1. // loop through all entries in hashmap
  1. Iterator iter = map.entrySet().iterator();
  1. while (iter.hasNext()) {
  1. Map.Entry entry = (Map.Entry)iter.next();
  1. ctx.startTagAttributes(m_index,ENTRY_ELEMENT_NAME);
  1. if (entry.getKey() != null) {
  1. ctx.attribute(m_index,KEY_ATTRIBUTE_NAME,
  1. entry.getKey().toString());
  1. }
  1. ctx.closeStartContent();
  1. if (entry.getValue() instanceof IMarshallable) {
  1. ((IMarshallable)entry.getValue()).marshal(ctx);
  1. ctx.endTag(m_index,monospace; direction:ltr; font-size:10pt; overflow:visible"> } "Mapped value is not marshallable");
  1. }
  1. // finish with end tag for container element
  1. ctx.endTag(m_index,m_name);
  1. }
  1. /* (non-Javadoc)
  1. * @see org.jibx.runtime.IUnmarshaller#isPresent(org.jibx.runtime.IUnmarshallingContext)
  1. boolean isPresent(IUnmarshallingContext ctx) throws JiBXException {
  1. return ctx.isAt(m_uri,m_name);
  1. * @see org.jibx.runtime.IUnmarshaller#unmarshal(java.lang.Object,
  1. * org.jibx.runtime.IUnmarshallingContext)
  1. public Object unmarshal(Object obj,IUnmarshallingContext ictx)
  1. // make sure we're at the appropriate start tag
  1. UnmarshallingContext ctx = (UnmarshallingContext)ictx;
  1. if (!ctx.isAt(m_uri,m_name)) {
  1. ctx.throwStartTagNameError(m_uri,0)">// create new hashmap if needed
  1. int size = ctx.attributeInt(m_uri,DEFAULT_SIZE);
  1. HashMap map = (HashMap)obj;
  1. if (map == null) {
  1. map = new HashMap(size);
  1. // process all entries present in document
  1. ctx.parsePastStartTag(m_uri,255)">while (ctx.isAt(m_uri,ENTRY_ELEMENT_NAME)) {
  1. 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();
  1. map.put(key,value);
  1. ctx.parsePastEndTag(m_uri,ENTRY_ELEMENT_NAME);
  1. ctx.parsePastEndTag(m_uri,255)">return map;
  1. boolean isExtension(String arg0) {
  1. return false;
  1. }

e) 然后运行Compile命令

E:\Study\WebHttpUtils>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}
  1. .com#china#2010-11-22

猜你在找的XML相关文章