用Castor 处理XML文档
——Castor可以完成Java和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的相互转换。它是怎么样转换的?和前面不同的是castor可以用一个mapping.xml文件来描述转换后的Java对象的xml基本形态,类似于xStream的annotation,这点还是非常不错的。下面我们就来看看Castor是怎么样完成 Java对象到XML之间的相互转换吧。
一、 准备工作
1、 官方资源
本示例会运用到如下依赖包(jar包):
资源及jar包下载:http://www.castor.org/download.html
junit jar下载地址:
https://github.com/KentBeck/junit/downloads
关于官方提供的mapping配置相关示例、文档:
http://www.castor.org/xml-mapping.html
ibm提供的castor方面的文档资料:
http://www.google.com.hk/search?hl=zh-CN&newwindow=1&safe=strict&client=aff-cs-360se&hs=Gon&biw=1349&bih=603&q=castor+site%3Awww.ibm.com%2Fdeveloperworks%2Fcn%2Fxml%2F&aq=f&aqi=&aql=&oq=
2、 程序测试运行代码
01 |
package com.hoo.test; |
02 |
|
03 |
import java.io.IOException; |
04 |
import java.io.StringReader; |
05 |
import java.io.StringWriter; |
06 |
import java.util.ArrayList; |
07 |
import java.util.HashMap; |
08 |
import java.util.List; |
09 |
import java.util.Map; |
10 |
import org.exolab.castor.mapping.Mapping; |
11 |
import org.exolab.castor.mapping.MappingException; |
12 |
import org.exolab.castor.xml.MarshalException; |
13 |
import org.exolab.castor.xml.Marshaller; |
14 |
import org.exolab.castor.xml.Unmarshaller; |
15 |
import org.exolab.castor.xml.ValidationException; |
16 |
import org.junit.After; |
17 |
import org.junit.Before; |
18 |
import org.junit.Test; |
19 |
import com.hoo.entity.Account; |
20 |
import com.hoo.entity.AccountArray; |
21 |
import com.hoo.entity.Birthday; |
22 |
import com.hoo.entity.ListBean; |
23 |
import com.hoo.entity.MapBean; |
24 |
|
25 |
/** |
26 |
* <b>function:</b>Castor完成Java对象到XML的相互转换 |
27 |
* 依赖jar: castor-1.3.jar |
28 |
* castor-1.3-core.jar |
29 |
* junit-4.8.2.jar |
30 |
* log4j-1.2.16.jar |
31 |
* commons-logging.jar |
32 |
* @author hoojo |
33 |
* @createDate 2011-4-21 下午07:57:26 |
34 |
* @file CastorTest.java |
35 |
* @package com.hoo.test |
36 |
* @project WebHttpUtils |
37 |
* @blog http://blog.csdn.net/IBM_hoojo |
38 |
* @email [email protected] |
39 |
* @version 1.0 |
40 |
*/ |
41 |
public class CastorTest { |
42 |
|
43 |
private Account bean = null ; |
44 |
private Mapping mapping = new Mapping(); |
45 |
private StringWriter writer = null ; |
46 |
private StringReader reader = null ; |
47 |
|
48 |
@Before |
49 |
public void init() { |
50 |
bean = new Account(); |
51 |
bean.setAddress( "北京" ); |
52 |
bean.setEmail( "email" ); |
53 |
bean.setId( 1 ); |
54 |
bean.setName( "jack" ); |
55 |
Birthday day = new Birthday(); |
56 |
day.setBirthday( "2010-11-22" ); |
57 |
bean.setBirthday(day); |
58 |
|
59 |
try { |
60 |
/** |
61 |
* 加载mapping.xml,此文件是对需要转换的Java对象的配置描述, |
62 |
* 即:转换后的Java对象的xml内容的转换规则 |
63 |
*/ |
64 |
mapping.loadMapping(System.getProperty( "user.dir" ) + "\\src\\mapping.xml" ); |
65 |
} catch (IOException e) { |
66 |
e.printStackTrace(); |
67 |
} catch (MappingException e) { |
68 |
e.printStackTrace(); |
69 |
} |
70 |
} |
71 |
|
72 |
@After |
73 |
public void destory() { |
74 |
bean = null ; |
75 |
mapping = null ; |
76 |
try { |
77 |
if (writer != null ) { |
78 |
writer.flush(); |
79 |
writer.close(); |
80 |
} |
81 |
if (reader != null ) { |
82 |
reader.close(); |
83 |
} |
84 |
} catch (IOException e) { |
85 |
e.printStackTrace(); |
86 |
} |
87 |
System.gc(); |
88 |
} |
89 |
|
90 |
public void fail(Object o) { |
91 |
System.out.println(o); |
92 |
} |
93 |
|
94 |
public void failRed(Object o) { |
95 |
System.err.println(o); |
96 |
} |
97 |
} |
Mapping对象可以完成Java对象到XML的编组和解组,它需要先设定一个mapping.xml,通过xml对JavaObject的描述。来完成JavaObject的编组、解组工作。
3、 看看即将被转换的JavaEntity代码
Account
01 |
package com.hoo.entity; |
02 |
|
03 |
public class Account { |
04 |
private int id; |
05 |
private String name; |
06 |
private String email; |
07 |
private String address; |
08 |
private Birthday birthday; |
09 |
|
10 |
//setter、getter |
11 |
@Override |
12 |
public String toString() { |
13 |
return this .id + "#" + this .name + "#" + this .email + "#" + this .address + "#" + this .birthday; |
14 |
} |
15 |
} |
16 |
|
17 |
Birthday |
18 |
|
19 |
package com.hoo.entity; |
20 |
|
21 |
public class Birthday { |
22 |
private String birthday; |
23 |
|
24 |
public Birthday(String birthday) { |
25 |
super (); |
26 |
this .birthday = birthday; |
27 |
} |
28 |
//getter、setter |
29 |
public Birthday() {} |
30 |
|
31 |
@Override |
32 |
public String toString() { |
33 |
return this .birthday; |
34 |
} |
35 |
} |
36 |
|
37 |
AccountArray |
38 |
|
39 |
package com.hoo.entity; |
40 |
|
41 |
public class AccountArray { |
42 |
private Account[] accounts; |
43 |
private int size; |
44 |
public int getSize() { |
45 |
size = accounts.length; |
46 |
return size; |
47 |
} |
48 |
public void setSize( int size) { |
49 |
this .size = size; |
50 |
} |
51 |
public Account[] getAccounts() { |
52 |
return accounts; |
53 |
} |
54 |
public void setAccounts(Account[] accounts) { |
55 |
this .accounts = accounts; |
56 |
} |
57 |
} |
58 |
|
59 |
ListBean |
60 |
|
61 |
package com.hoo.entity; |
62 |
|
63 |
import java.util.List; |
64 |
|
65 |
public class ListBean { |
66 |
private String name; |
67 |
private List list; |
68 |
//setter、getter |
69 |
} |
70 |
|
71 |
MapBean |
72 |
|
73 |
package com.hoo.entity; |
74 |
|
75 |
import java.util.Map; |
76 |
|
77 |
public class MapBean { |
78 |
private Map<String, Object> map; |
79 |
|
80 |
public Map<String, Object> getMap() { |
81 |
return map; |
82 |
} |
83 |
public void setMap(Map<String, Object> map) { |
84 |
this .map = map; |
85 |
} |
86 |
} |
二、 编组JavaObject到XML
1、 将JavaBean编组,转换成XML
01 |
/** |
02 |
* <b>function:</b>将Javabean编组,转换成XML |
03 |
* @author hoojo |
04 |
* @createDate 2011-4-22 下午12:08:48 |
05 |
*/ |
06 |
@Test |
07 |
public void writeBean2XML() { |
08 |
writer = new StringWriter(); |
09 |
try { |
10 |
//编组 |
11 |
Marshaller.marshal(bean, writer); |
12 |
fail(writer); |
13 |
} catch (MarshalException e) { |
14 |
e.printStackTrace(); |
15 |
} catch (Exception e) { |
16 |
e.printStackTrace(); |
17 |
} |
18 |
} |
代码很简单,通过Marshaller的marshal方法来完成Java对象到XML的编组(序列化、转换)工作。
运行后的结果如下:
<?xml version="1.0" encoding="UTF-8"?>
<account id="1"><address>北京</address><email>email</email><name>jack</name>
<birthday><birthday>2010-11-22</birthday></birthday></account>
2、 将List集合转换成XML
01 |
/** |
02 |
* <b>function:</b>将List转换成xml |
03 |
* @author hoojo |
04 |
* @createDate 2011-4-22 下午12:11:00 |
05 |
*/ |
06 |
@Test |
07 |
public void writeList2XML() { |
08 |
writer = new StringWriter(); |
09 |
List<Account> list = new ArrayList<Account>(); |
10 |
list.add(bean); |
11 |
bean = new Account(); |
12 |
bean.setName( "tom" ); |
13 |
bean.setId( 223 ); |
14 |
list.add(bean); |
15 |
try { |
16 |
Marshaller.marshal(list, writer); |
17 |
fail(writer); |
18 |
} catch (MarshalException e) { |
19 |
e.printStackTrace(); |
20 |
} catch (Exception e) { |
21 |
e.printStackTrace(); |
22 |
} |
23 |
} |
运行后,结果如下:
1 |
<? xml version = "1.0" encoding = "UTF-8" ?> |
2 |
< array-list > |
3 |
< account xmlns:xsi = "http://www.w3.org/2001/XMLSchema-instance" xmlns:java = "http://java.sun.com" id = "1" xsi:type = "java:com.hoo.entity.Account" > |
4 |
< address >北京</ address >< email >email< / email >< name >jack</ name >< birthday >< birthday >2010-11-22</ birthday ></ birthday ></ account > |
5 |
< account xmlns:xsi = "http://www.w3.org/2001/XMLSchema-instance" xmlns:java = "http://java.sun.com" id = "223" xsi:type = "java:com.hoo.entity.Account" > |
6 |
< name >tom</ name > |
7 |
</ account > |
8 |
</ array-list > |
怎么样,List存放的是2个Account吧。
3、 将Array数组转换成XML
01 |
/** |
02 |
* <b>function:</b>将Array数组转换成XML |
03 |
* @author hoojo |
04 |
* @createDate 2011-4-22 下午12:11:25 |
05 |
*/ |
06 |
@Test |
07 |
public void writeArray2XML() { |
08 |
writer = new StringWriter(); |
09 |
Account[] acc = new Account[ 2 ]; |
10 |
acc[ 0 ] = bean; |
11 |
bean = new Account(); |
12 |
bean.setName( "tom" ); |
13 |
bean.setId( 223 ); |
14 |
acc[ 1 ] = bean; |
15 |
|
16 |
try { |
17 |
Marshaller.marshal(acc, writer); |
18 |
fail(writer); |
19 |
} catch (MarshalException e) { |
20 |
e.printStackTrace(); |
21 |
} catch (Exception e) { |
22 |
e.printStackTrace(); |
23 |
} |
24 |
} |
结果如下:
1 |
<? xml version = "1.0" encoding = "UTF-8" ?> |
2 |
< array >< account id = "1" >< address >北京</ address >< email >email</ email & gt;<name>jack</ name > |
3 |
< birthday >< birthday >2010-11-22</ birthday ></ birthday ></ account > |
4 |
< account id = "223" >< name >tom</ name ></ account ></ array > |
4、 转换其他Java类型
01 |
/** |
02 |
* <b>function:</b>将Java常用类型编组成xml |
03 |
* @author hoojo |
04 |
* @createDate 2011-4-22 下午12:11:44 |
05 |
*/ |
06 |
@Test |
07 |
public void writeObject2XML() { |
08 |
writer = new StringWriter(); |
09 |
try { |
10 |
Marshaller.marshal( true , writer); |
11 |
Marshaller.marshal( 9527 , writer); |
12 |
Marshaller.marshal( 2 .2f, writer); |
13 |
Marshaller.marshal( 1 .11d, writer); |
14 |
Marshaller.marshal( "lucy" , writer); |
15 |
Marshaller.marshal( "hello castor" .getBytes(), writer); |
16 |
Marshaller.marshal( new char [] { 'a' , 'b' , 'c' }, writer); |
17 |
Marshaller.marshal( new String[] { "hi" , "spring" , "castor" }, writer); |
18 |
fail(writer); |
19 |
} catch (MarshalException e) { |
20 |
e.printStackTrace(); |
21 |
} catch (Exception e) { |
22 |
e.printStackTrace(); |
23 |
} |
24 |
} |
结果如下:
1 |
<? xml version = "1.0" encoding = "UTF-8" ?> |
2 |
< boolean >true</ boolean ><? xml version = "1.0" encoding = "UTF-8" ?> |
3 |
< integer >9527</ integer ><? xml version = "1.0" encoding = "UTF-8" ?> |
4 |
< float >2.2</ float ><? xml version = "1.0" encoding = "UTF-8" ?> |
5 |
< double >1.11</ double ><? xml version = "1.0" encoding = "UTF-8" ?> |
6 |
< string >lucy</ string ><? xml version = "1.0" encoding = "UTF-8" ?> |
7 |
<[-b>aGVsbG8gY2FzdG9y</[-b><? xml version = "1.0" encoding = "UTF-8" ?> |
8 |
< array >< character >a</ character >< character >b</ character >< character >c</ character ></ array ><? xml version = "1.0" encoding = "UTF-8" ?> |
9 |
< array >< string >hi</ string >< string >spring</ string >< string >castor</ string ></ array > |
都是类型为节点名称,值为text。但是这里并没有出现Map,如果转换Map需要mapping进行配置。下面再慢慢道来-.-
5、 将xml解组成JavaBean
01 |
/** |
02 |
* <b>function:</b>将XML内容,解组成JavaBean |
03 |
* @author hoojo |
04 |
* @createDate 2011-4-22 下午12:12:14 |
05 |
*/ |
06 |
@Test |
07 |
public void readXML2Bean() { |
08 |
|
09 |
String xml = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>" + |
10 |
"<account id=\"1\"><address>北京</address>" + |
11 |
"<name>jack</name><email>email</email>" + |
12 |
"<birthday><birthday>2010-11-22</birthday></birthday></account>" ; |
13 |
reader = new StringReader(xml); |
14 |
|
15 |
try { |
16 |
//解组 |
17 |
Account account = (Account) Unmarshaller.unmarshal(Account. class , reader); |
18 |
fail(account); |
19 |
} catch (MarshalException e) { |
20 |
e.printStackTrace(); |
21 |
} catch (ValidationException e) { |
22 |
e.printStackTrace(); |
23 |
} |
24 |
} |
结果如下:
1#jack#email#北京#2010-11-22
其他的类型,如:map、list、array都不能成功解组。因为这些类型里面有很多系统默认的xml描述。但是利用mapping和自定义JavaBean就可以成功编组和解组了。下面看看mapping是怎么玩转这些类型的。
三、 利用mapping配置,编组JavaObject、解组XML
最开始的init方法就提供了mapping,让我们对mapping这个配置有了大概的了解。下面我们将详细介绍mapping是个什么:
1、 在此之前我们设置过mapping.xml。如果不设置,肯定是不能转换成我们想要的XML的。那么,mapping.xml配置文件是怎么配置Account这个对象的呢?
mapping.xml配置如下:
01 |
<? xml version = "1.0" encoding = "UTF-8" ?> |
02 |
<!DOCTYPE mapping PUBLIC "-//EXOLAB/Castor Mapping DTD Version 1.0//EN" "http://castor.org/mapping.dtd"> |
03 |
< mapping > |
04 |
< class name = "com.hoo.entity.Account" auto-complete = "true" > |
05 |
< map-to xml = "Account" /> |
06 |
|
07 |
< field name = "id" type = "integer" > |
08 |
< bind-xml name = "id" node = "attribute" /> |
09 |
</ field > |
10 |
|
11 |
< field name = "name" type = "string" > |
12 |
< bind-xml name = "name" node = "element" /> |
13 |
</ field > |
14 |
|
15 |
< field name = "email" type = "string" > |
16 |
< bind-xml name = "email" node = "element" /> |
17 |
</ field > |
18 |
|
19 |
< field name = "address" type = "string" > |
20 |
< bind-xml name = "address" node = "element" /> |
21 |
</ field > |
22 |
|
23 |
< field name = "birthday" type = "com.hoo.entity.Birthday" > |
24 |
< bind-xml name = "生日" node = "element" /> |
25 |
</ field > |
26 |
</ class > |
27 |
|
28 |
< class name = "com.hoo.entity.Birthday" > |
29 |
< map-to xml = "birthday" /> |
30 |
|
31 |
< field name = "birthday" type = "string" > |
32 |
< bind-xml name = "birthday" node = "attribute" /> |
33 |
</ field > |
34 |
</ class > |
35 |
</ mapping > |
首先,看看这个xml文档的根元素是mapping,在mapping中可以配置class。也就是我们要转换的JavaObject的配置描述了。
class元素的name属性就是配置的JavaObject的classpath路径了。
关于class元素的auto-complate属性,如果这个属性的值为ture。那么编组后的xml,castor会自动给没有在mapping配置文件进行配置的属性自动编组(转换)到xml中。如果为false,那么在mapping配置文件中出现的属性将在编组后不现在在编组后的xml中。
map-to就是当前class编组后的xml文档的节点元素名称。
field就是描述JavaObject中的属性,name是Java对象的属性名称,type是类型。关于配置的type类型也有规定,你可以参考:http://www.castor.org/xml-mapping.html的field配置讲解。
而field还有其他的属性配置,如get-method应该是getter方法、set-method应该是setter的方法、has-mehtod 应该是hashCode方法,有时候我们不一定要提高getter、setter方法,我们需要用自己的方法名称来代替setter、getter。如果当前field配置的是集合类型,那么你需要给field元素配置collection属性。
bind-xml就是绑定(编组)成xml后的xml内容的描述,name就是编组后xml的节点元素名称,node有2个值,分别是 attribute、element。attribute是属性,它会在节点元素的属性中显示,例如:<account id=”2”></account>
而element则是单独的一个元素,例如:<account><id>2</id></account>
就这个样子的。
mapping.xml还可以有其他标签,如:
<include href="other_mapping_file.xml"/>
导入外部xml文件,可以分多个配置。
好了,先将这么多的mapping方面的内容。我们还是看看实际运行的示例吧,代码如下:
/**
* <b>function:</b>将XML内容解组成Java对象
* @author hoojo
* @createDate 2011-4-22 下午12:13:28
*/
@Test
public void bean4Mapping2XML() {
writer = new StringWriter();
try {
//编组
Marshaller mar = new Marshaller(writer);
mar.setMapping(mapping);
mar.marshal(bean);
fail(writer);
//解组
reader = new StringReader(writer.toString());
Unmarshaller unmar = new Unmarshaller(Account.class);
unmar.setMapping(mapping);
Account account = (Account) unmar.unmarshal(reader);
fail(account);
} catch (MarshalException e) {
e.printStackTrace();
} catch (Exception e) {
e.printStackTrace();
}
}
运行后结果如下:
<?xml version="1.0" encoding="UTF-8"?>
<Account id="1"><name>jack</name><email>email</email>& lt;address>北京</address><生日 birthday="2010-11-22"/></Account>
1#jack#email#北京#2010-11-22
上面的xml的根节点是Account,这个功劳就来源于mapping配置中的map-to元素,而根节点的id属性是有field和bind-xml 来完成的。当bind-xml的node值为attribute时,就会以属性的方式显示。当node为element时,就会像后面name、 email一样,以元素名称显示。
再看看上面的mapping文件中的Account的配置,有个auto-complate属性,如果把这个属性的值设置成false,会怎么样?那我们赶紧试试。
没有发现上面异样,但是当我们删除下面配置的filed的时候,就发现有变化了。
结果如下:
<?xml version="1.0" encoding="UTF-8"?>
<Account><name>jack</name><email>email< /email><address>北京</address><生日 birthday="2010-11-22"/></Account>
0#jack#email#北京#2010-11-22
发现id没有显示在xml中,那么我们再将auto-complate的属性设置true,会有什么惊喜?
结果如下:
<?xml version="1.0" encoding="UTF-8"?>
<Account id="1"><name>jack</name><email>email</email>& lt;address>北京</address><生日 birthday="2010-11-22"/></Account>
1#jack#email#北京#2010-11-22
发现id又回来了,但是Account的配置中并没有配置id的field。这是为什么,其实auto-comlate在上面已经讲过了。Castor在编组时会自动将int类型的属性,显示在父元素的属性中。并且JavaObject中有的属性没有在mapping配置文件中配置,castor也会自动将其编组在xml中。
下面我们看看map-to配置的用法,map-to的主要属性是name,也就是我们把当前根元素重命名的名称。Map-to还有2个属性可以用,分别是 ns-uri、ns-prefix。看名称就知道它大概的意识,一个是命名空间的uri另一个则是命名空间的前缀。我们给上面mapping加上这两个属性看看。
<map-to xml="Account" ns-uri="http://hoojo.cnblogs.com" ns-prefix="castor"/>
结果如下:
<?xml version="1.0" encoding="UTF-8"?>
<castor:Account xmlns:castor="http://hoojo.cnblogs.com" id="1"><castor:name>jack</castor:name><castor:email>email</castor:email>
<castor:address>北京</castor:address><castor:生日 birthday="2010-11-22"/></castor:Account>
1#jack#email#北京#2010-11-22
发现了什么?节点元素都带上了ns-prefix的值,而根元素则有了xml的ns。
2、 将一段XML格式字符串转换成JavaBean
@Test
public void readBean4Mapping2XML() {
String xml = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>" +
"<Account id=\"2241\"><name>jack</name><email>email< /email><address>北京</address><生日 birthday=\"2010-11-22\"/></Account>";
try {
reader = new StringReader(xml);
Unmarshaller unmar = new Unmarshaller(Account.class);
unmar.setMapping(mapping);
Account account = (Account) unmar.unmarshal(reader);
fail(account);
} catch (MarshalException e) {
e.printStackTrace();
} catch (Exception e) {
e.printStackTrace();
}
}
运行后结果如下:
2241#jack#email#北京#2010-11-22
3、 将XML内容解组成Java的Array
/**
* <b>function:</b>将XML内容解组成Java的Array
* @author hoojo
* @createDate 2011-4-22 下午12:14:50
*/
@Test
public void array4Mapping2XML() {
writer = new StringWriter();
Account[] acc = new Account[2];
acc[0] = bean;
bean = new Account();
bean.setName("tom");
bean.setId(223);
acc[1] = bean;
AccountArray array = new AccountArray();
array.setAccounts(acc);
try {
Marshaller mar = new Marshaller(writer);
mar.setMapping(mapping);
mar.marshal(array);
fail(writer);
reader = new StringReader(writer.toString());
Unmarshaller unmar = new Unmarshaller(AccountArray.class);
unmar.setMapping(mapping);
array = (AccountArray) unmar.unmarshal(reader);
fail(array.getSize());
fail(array.getAccounts()[0]);
fail(array.getAccounts()[1]);
} catch (MarshalException e) {
e.printStackTrace();
} catch (Exception e) {
e.printStackTrace();
}
}
AccountArray的mapping配置如下:
<class name="com.hoo.entity.AccountArray">
<map-to xml="account-array"/>
<field name="size" type="int" />
<field name="accounts" collection="array" type="com.hoo.entity.Account">
<bind-xml name="accounts" auto-naming="deriveByClass"/>
</field>
</class>
collection表示是数组,auto-maming有2中值,一种是类driverByClass,另一种则是driverByField是属性。
运行后,结果如下:
<?xml version="1.0" encoding="UTF-8"?>
<account-array><size>2</size><Account id="1"><name>jack</name><email>email</email>& lt;address>北京</address>
<生日 birthday="2010-11-22"/></Account><Account id="223"><name>tom</name></Account></account-array>
2
1#jack#email#北京#2010-11-22
223#tom#null#null#null
4、 将Map编组、解组成JavaObject
/**
* <b>function:</b>xml转换成Java的Map
* @author hoojo
* @createDate 2011-4-22 下午12:15:18
*/
@Test
public void map4Mapping2XML() {
writer = new StringWriter();
MapBean mapBean = new MapBean();
Map<String, Object> map = new HashMap<String, Object>();
map.put("No1", bean);
bean = new Account();
bean.setName("tom");
bean.setId(223);
map.put("No2", bean);
mapBean.setMap(map);
try {
Marshaller mar = new Marshaller(writer);
mar.setMapping(mapping);
mar.marshal(mapBean);
fail(writer);
reader = new StringReader(writer.toString());
Unmarshaller unmar = new Unmarshaller(MapBean.class);
unmar.setMapping(mapping);
mapBean = (MapBean) unmar.unmarshal(reader);
fail(mapBean.getMap());
} catch (MarshalException e) {
e.printStackTrace();
} catch (Exception e) {
e.printStackTrace();
}
}
Mapping配置
<class name="com.hoo.entity.MapBean">
<field name="map" collection="map">
<bind-xml name="map">
<class name="org.exolab.castor.mapping.MapItem">
<field name="key" type="java.lang.String">
<bind-xml name="key" node="attribute" />
</field>
<field name="value" type="com.hoo.entity.Account">
<bind-xml name="value" auto-naming="deriveByClass"/>
</field>
</class>
</bind-xml>
</field>
</class>
上面的map配置必须这样配置,利用org.exolab.castor.mapping.MapItem这个class,完成key、value的配置。
结果如下:
<?xml version="1.0" encoding="UTF-8"?>
<map-bean><map key="No2"><Account id="223"><name>tom</name></Account></map>
<map key="No1"><Account id="1"><name>jack</name><email>email</email>& lt;address>北京</address>
<生日 birthday="2010-11-22"/></Account></map></map-bean>
{No2=223#tom#null#null#null, No1=1#jack#email#北京#2010-11-22}
5、 JavaList编组、解组XML
/**
* <b>function:</b>List到XML的相互转换
* @author hoojo
* @createDate 2011-4-22 下午12:16:04
*/
@SuppressWarnings("unchecked")
@Test
public void listForMapping2XML() {
writer = new StringWriter();
List<Account> list = new ArrayList<Account>();
list.add(bean);
bean = new Account();
bean.setName("tom");
bean.setId(223);
list.add(bean);
ListBean listBean = new ListBean();
listBean.setList(list);
try {
Marshaller mar = new Marshaller(writer);
mar.setMapping(mapping);
mar.marshal(listBean);
fail(writer);
reader = new StringReader(writer.toString());
Unmarshaller unmar = new Unmarshaller(ListBean.class);
unmar.setMapping(mapping);
listBean = (ListBean) unmar.unmarshal(reader);
fail(listBean.getList().size());
for (Account acc : (List<Account>)listBean.getList()) {
fail(acc);
}
} catch (MarshalException e) {
e.printStackTrace();
} catch (Exception e) {
e.printStackTrace();
}
}
Mapping配置
<class name="com.hoo.entity.ListBean">
<map-to xml="listBean"/>
<field name="list" collection="arraylist" type="com.hoo.entity.Account">
<bind-xml name="beans" auto-naming="deriveByClass"/>
</field>
</class>
结果:
<?xml version="1.0" encoding="UTF-8"?>
<listBean><Account id="1"><name>jack</name><email>email</email>& lt;address>北京</address>
<生日 birthday="2010-11-22"/></Account><Account id="223"><name>tom</name></Account></listBean>
2
1#jack#email#北京#2010-11-22
223#tom#null#null#null