解析xml一般有sax,pull,dom,对与复杂的xml,sax或者pull可能会繁琐了一点,dom应该还行,关于之间的优缺点,网上介绍的很多,在此就不啰嗦了,今天写这个不是用dom去解析复杂的xml,而是用XStream去解析,可以很方便的解析出来。XStream官方介绍(http://xstream.codehaus.org/tutorial.html),里面用法介绍很全面,下面只是简单备注下,留日后可以快速浏览。
下面是需要解析的xml
创建对应的实体类,Blog,Author和Entry(对应的类在这就不写了,需要说下的是,里面的属性可以没有setter和getter方法,xstram通过反射给里面的属性赋值的),解析上面xml的时候,注意这些实体类必须用空参数构造方法。
将实体转化成xml,调用 xstream.toXML(Object),更多使用请参考XSream官网。
网上另找的不错的例子:
https://www.oschina.net/code/snippet_116183_14202
String xmlStr=
"<person>"
+
"<firstName>chen</firstName>"
+
"<lastName>youlong</lastName>"
+
"<telphone>"
+
"<code>137280</code>"
+
"<number>137280968</number>"
+
"</telphone>"
+
"<faxphone>"
+
"<code>20</code>"
+
"<number>020221327</number>"
+
"</faxphone>"
+
"<friends>"
+
"<name>A1</name>"
+
"<name>A2</name>"
+
"<name>A3</name>"
+
"</friends>"
+
"<pets>"
+
"<pet>"
+
"<name>doly</name>"
+
"<age>2</age>"
+
"</pet>"
+
"<pet>"
+
"<name>Ketty</name>"
+
"<age>2</age>"
+
"</pet>"
+
"</pets>"
+
"</person>"
;
1. [代码]1.实体类:PersonBean
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
|
import
java.util.List;
import
com.thoughtworks.xstream.annotations.XStreamAlias;
import
com.thoughtworks.xstream.annotations.XStreamImplicit;
/**
*@ClassName:PersonBean
*@author: chenyoulong Email: chen.youlong@payeco.com
*@date :2012-9-28 下午3:10:47
*@Description:TODO
*/
@XStreamAlias
(
"person"
)
public
class
PersonBean {
@XStreamAlias
(
"firstName"
)
private
String firstName;
@XStreamAlias
(
"lastName"
)
private
String lastName;
@XStreamAlias
(
"telphone"
)
private
PhoneNumber tel;
@XStreamAlias
(
"faxphone"
)
private
PhoneNumber fax;
//测试一个标签下有多个同名标签
@XStreamAlias
(
"friends"
)
private
Friends friend;
//测试一个标签下循环对象
@XStreamAlias
(
"pets"
)
private
Pets pet;
//省略setter和getter
}
|
2. [代码]2.实体类:PhoneNumber
1
2
3
4
5
6
7
8
9
10
|
@XStreamAlias
(
"phoneNumber"
)
public
class
PhoneNumber{
@XStreamAlias
(
"code"
)
private
int
code;
@XStreamAlias
(
"number"
)
private
String number;
//省略setter和getter
}
|
3. [代码]3.实体类:Friends(一个标签下有多个同名标签 )
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
|
/**
* 用Xstream注解的方式实现:一个标签下有多个同名标签
*@ClassName:Friends
*@author: chenyoulong Email: chen.youlong@payeco.com
*@date :2012-9-28 下午4:32:24
*@Description:TODO 5个name 中国,美国,俄罗斯,英国,法国
*http://blog.csdn.net/menhuanxiyou/article/details/5426765
*/
public
static
class
Friends{
@XStreamImplicit
(itemFieldName=
"name"
)
//itemFieldName定义重复字段的名称,
/*<friends> <friends>
<name>A1</name> <String>A1</String>
<name>A2</name> 如果没有,则会变成 =====> <String>A1</String>
<name>A3</name> <String>A1</String>
</friends> </friends>
*/
private
List<String> name;
public
List<String> getName() {
return
name;
}
public
void
setName(List<String> name) {
this
.name = name;
}
}
|
4. [代码]4.1实体类:Animal(同一标签下循环对象实体1)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
|
//测试同一标签下循环某一对象
public
class
Animal{
@XStreamAlias
(
"name"
)
private
String name;
@XStreamAlias
(
"age"
)
private
int
age;
public
Animal(String name,
int
age){
this
.name=name;
this
.age=age;
}
//省略setter和getter
}
|
5. [代码]4.2实体类:Pets(同一标签下循环对象实体2)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
|
/**
* 测试同一标签下循环某一对象
*@ClassName:Pets
*@author: chenyoulong Email: chen.youlong@payeco.com
*@date :2012-9-28 下午6:26:01
*@Description:TODO
*/
public
class
Pets{
@XStreamImplicit
(itemFieldName=
"pet"
)
private
List<Animal> animalList;
public
List<Animal> getAnimalList() {
return
animalList;
}
public
void
setAnimalList(List<Animal> animalList) {
this
.animalList = animalList;
}
}
|
PersonBean person = XmlUtil.toBean(xmlStr, PersonBean.class);
System.out.println("person=firstname==" + person.getFirstName());
System.out.println("person==Friends==name1=="
+ person.getFriend().getName().get(0));
System.out.println("person==Pets==name2=="
+ person.getPet().getAnimalList().get(1).getName());
9. [代码]6.XmlUtil工具类(toxml()和toBean()) 跳至[1][2] [3] [4] [5] [6] [7] [8] [9] [全屏预览]
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
|
/**
* 输出xml和解析xml的工具类
*@ClassName:XmlUtil
*@author: chenyoulong Email: chen.youlong@payeco.com
*@date :2012-9-29 上午9:51:28
*@Description:TODO
*/
public
class
XmlUtil{
/**
* java 转换成xml
* @Title: toXml
* @Description: TODO
* @param obj 对象实例
* @return String xml字符串
*/
public
static
String toXml(Object obj){
XStream xstream=
new
XStream();
// XStream xstream=new XStream(new DomDriver()); //直接用jaxp dom来解释
// XStream xstream=new XStream(new DomDriver("utf-8")); //指定编码解析器,直接用jaxp dom来解释
如果没有这句,xml中的根元素会是<包.类名>;或者说:注解根本就没生效,所以的元素名就是类的属性
xstream.processAnnotations(obj.getClass());
//通过注解方式的,一定要有这句话
return
xstream.toXML(obj);
}
/**
* 将传入xml文本转换成Java对象
* @Title: toBean
* @Description: TODO
* @param xmlStr
* @param cls xml对应的class类
* @return T xml对应的class类的实例对象
*
* 调用的方法实例:PersonBean person=XmlUtil.toBean(xmlStr, PersonBean.class);
*/
public
static
<T> T toBean(String xmlStr,Class<T> cls){
//注意:不是new Xstream(); 否则报错:java.lang.NoClassDefFoundError: org/xmlpull/v1/XmlPullParserFactory
XStream xstream=
new
XStream(
new
DomDriver());
xstream.processAnnotations(cls);
T obj=(T)xstream.fromXML(xmlStr);
return
obj;
}
/**
* 写到xml文件中去
* @Title: writeXMLFile
* @Description: TODO
* @param obj 对象
* @param absPath 绝对路径
* @param fileName 文件名
* @return boolean
*/
public
static
boolean
toXMLFile(Object obj, String absPath, String fileName ){
String strXml = toXml(obj);
String filePath = absPath + fileName;
File file =
new
File(filePath);
if
(!file.exists()){
try
{
file.createNewFile();
}
catch
(IOException e) {
log.error(
"创建{"
+ filePath +
"}文件失败!!!"
+ Strings.getStackTrace(e));
return
false
;
}
}
// end if
OutputStream ous =
null
;
try
{
ous =
new
FileOutputStream(file);
ous.write(strXml.getBytes());
ous.flush();
}
catch
(Exception e1) {
log.error(
"写{"
+ filePath +
"}文件失败!!!"
+ Strings.getStackTrace(e1));
return
false
;
}
finally
{
if
(ous !=
null
)
try
{
ous.close();
}
catch
(IOException e) {
log.error(
"写{"
+ filePath +
"}文件关闭输出流异常!!!"
+ Strings.getStackTrace(e));
}
}
return
true
;
}
/**
* 从xml文件读取报文
* @Title: toBeanFromFile
* @Description: TODO
* @param absPath 绝对路径
* @param fileName 文件名
* @param cls
* @throws Exception
* @return T
*/
public
static
<T> T toBeanFromFile(String absPath, String fileName,Class<T> cls)
throws
Exception{
String filePath = absPath +fileName;
InputStream ins =
null
;
try
{
ins =
new
FileInputStream(
new
File(filePath ));
}
catch
(Exception e) {
throw
new
Exception(
"读{"
+ filePath +
"}文件失败!"
, e);
}
String encode = useEncode(cls);
XStream xstream=
new
XStream(
new
DomDriver(encode));
xstream.processAnnotations(cls);
T obj =
null
;
try
{
obj = (T)xstream.fromXML(ins);
}
catch
(Exception e) {
// TODO Auto-generated catch block
throw
new
Exception(
"解析{"
+ filePath +
"}文件失败!"
,e);
}
if
(ins !=
null
)
ins.close();
return
obj;
}
}
|