Java获取并解析XML(JavaBean和XML的转化)

Posted by Steven on 2019-12-05

最近遇到一个问题,需要从一个url获取xml文档并解析,google了很多方法,大多数都
是获取到XML然后循环遍历拿到数据,但是感觉很麻烦,并且感觉当数据量比较大的时候效率也不怎么
高,后面研究了下,发现JAXB这个好东西,可以实现JavaBean和XML节点元素的互相转换,故此总结一
下:

1、相关链接

2、准备工作

需要安装JAXB和dom4j,如果用的Maven,可以访问上面的url,并搜索JAXB和dom4j,选择需要的版本
,复制下面的代码配置到自己的项目中:

3、获取并解析

先看一下返回的XML格式

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
<HotelGeos>
<HotelGeoList>
<HotelGeo CityCode="0101" CityName="北京市" Country="中国" ProvinceId="0100" ProvinceName="北京市">
<CommericalLocations>
<Location Id="010103" Name="天安门/王府井商业区"/>
<Location Id="010119" Name="前门/大栅栏"/>
</CommericalLocations>
<Districts>
<Location Id="0001" Name="浦东新区"/>
<Location Id="0028" Name="闵行区"/>
</Districts>
<LandmarkLocations>
<Location Id="60000283" Name="上海虹桥站"/>
<Location Id="60000282" Name="上海站"/>
</LandmarkLocations>
</HotelGeo>
</HotelGeoList>
</HotelGeos>
解析
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
public static void main(String[] args) {
//获取XML
SAXReader reader = new SAXReader();
org.dom4j.Document document = reader.read(new URL("http://api.*************************/v2.0/hotel/geo_cn.xml")));
String documentStr = document.asXML();
//将xml字符串转换为java对象
JaxbUtil resultBinder = new JaxbUtil(HotelGeos.class, JaxbUtil.CollectionWrapper.class);
HotelGeos hotelObj = resultBinder.fromXml(documentStr);
//将java对象转换为XML字符串
HotelGeos hotelGeos=new HotelGeos();
List<HotelGeo> hotelGeoList=new ArrayList<>();
HotelGeo hotelGeo =new HotelGeo();
hotelGeo.setCityCode("0101");
hotelGeo.setCityName("北京市");
hotelGeo.setCountry("中国");
hotelGeo.setProvinceId("0100");
hotelGeo.setProvinceName("北京市");
//其他层级的这里就不一一赋值了
hotelGeoList.add(hotelGeo);
hotelGeos.setHotelGeoList(hotelGeoList);
JaxbUtil requestBinder = new JaxbUtil(HotelGeos.class, CollectionWrapper.class);
String retXml = requestBinder.toXml(hotelGeos, "utf-8");
System.out.println("xml:"+retXml);
}
相关类之HotelGeos
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
package com .*****.geoData.items;
import lombok.Data;
import javax.xml.bind.annotation .*;
import java.util.List;

/**
* Created by IntelliJ IDEA.
* User: Steven
* Date: 2019/12/05
* Time: 13:36
*/
@Data
@XmlRootElement(name = "HotelGeos")
public class HotelGeos {
@XmlElementWrapper(name = "HotelGeoList")
@XmlElement(name = "HotelGeo")
private List<HotelGeo> HotelGeoList;
}
HotelGeo
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
package com.***.geoData.items;
import lombok.Data;
import org.codehaus.jackson.map.annotate.JsonSerialize;
import javax.xml.bind.annotation.XmlAttribute;
import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlElementWrapper;
import java.io.Serializable;
import java.util.List;
/**
* Created by IntelliJ IDEA.
* User: Steven
* Date: 2019/12/06
* Time: 13:38
*/
@Data
@JsonSerialize(include = JsonSerialize.Inclusion.NON_NULL)
public class HotelGeo implements Serializable {
@XmlAttribute(name = "CityCode")
private String CityCode;
@XmlAttribute(name = "CityName")
private String CityName;
@XmlAttribute(name = "Country")
private String Country;
@XmlAttribute(name = "ProvinceId")
private String ProvinceId;
@XmlAttribute(name = "ProvinceName")
private String ProvinceName;
@XmlElementWrapper(name = "CommericalLocations")
@XmlElement(name = "Location") //这里需要格外注意,层级很容易写错
private List<Location> CommericalLocations;
@XmlElementWrapper(name = "Districts")
@XmlElement(name = "Location")
private List<Location> Districts;
@XmlElementWrapper(name = "LandmarkLocations")
@XmlElement(name = "Location")
private List<Location> LandmarkLocations;
}
Location
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
package com.*****.geoData.items;
import lombok.Data;
import org.codehaus.jackson.map.annotate.JsonSerialize;
import javax.xml.bind.annotation.XmlAttribute;
import java.io.Serializable;
/**
* Created by IntelliJ IDEA.
* User: Steven
* Date: 2019/12/06
* Time: 13:53
*/
@Data
@JsonSerialize(include = JsonSerialize.Inclusion.NON_NULL)
public class Location implements Serializable {
@XmlAttribute(name = "Id")
private String Id;
@XmlAttribute(name = "Name")
private String Name;
}
JaxbUtil工具类
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
120
121
122
123
124
125
126
127
128
129
130

package com.*****.utils;
import java.io.StringReader;
import java.io.StringWriter;
import java.util.Collection;
import javax.xml.bind.JAXBContext;
import javax.xml.bind.JAXBElement;
import javax.xml.bind.JAXBException;
import javax.xml.bind.Marshaller;
import javax.xml.bind.Unmarshaller;
import javax.xml.bind.annotation.XmlAnyElement;
import javax.xml.namespace.QName;
import org.apache.commons.lang.StringUtils;
/**
* 使用Jaxb2.0实现XML<->Java Object的Binder.
*
* 特别支持Root对象是List的情形.
*
* @author
*/public class JaxbUtil {
// 多线程安全的Context.
private JAXBContext jaxbContext;
/**
* @param types
* 所有需要序列化的Root对象的类型.
*/
public JaxbUtil(Class<?>... types) {
try {
jaxbContext = JAXBContext.newInstance(types);
} catch (JAXBException e) {
throw new RuntimeException(e);
}
}
/**
* Java Object->Xml.
*/
public String toXml(Object root, String encoding) {
try {
StringWriter writer = new StringWriter();
createMarshaller(encoding).marshal(root, writer);
return writer.toString();
} catch (JAXBException e) {
throw new RuntimeException(e);
}
}
/**
* Java Object->Xml, 特别支持对Root Element是Collection的情形.
*/
@SuppressWarnings("unchecked")
public String toXml(Collection root, String rootName, String encoding) {
try {
CollectionWrapper wrapper = new CollectionWrapper();
wrapper.collection = root;
JAXBElement<CollectionWrapper> wrapperElement = new JAXBElement<CollectionWrap
per>(
new QName(rootName), CollectionWrapper.class, wrapper);
StringWriter writer = new StringWriter();
createMarshaller(encoding).marshal(wrapperElement, writer);
return writer.toString();
} catch (JAXBException e) {
throw new RuntimeException(e);
}
}/**
* Xml->Java Object.
*/
@SuppressWarnings("unchecked")
public <T> T fromXml(String xml) {
try {
StringReader reader = new StringReader(xml);
return (T) createUnmarshaller().unmarshal(reader);
} catch (JAXBException e) {
throw new RuntimeException(e);
}
}
/**
* Xml->Java Object, 支持大小写敏感或不敏感.
*/
@SuppressWarnings("unchecked")
public <T> T fromXml(String xml, boolean caseSensitive) {
try {
String fromXml = xml;
if (!caseSensitive)
fromXml = xml.toLowerCase();
StringReader reader = new StringReader(fromXml);
return (T) createUnmarshaller().unmarshal(reader);
} catch (JAXBException e) {
throw new RuntimeException(e);
}
}
/**
* 创建Marshaller, 设定encoding(可为Null).
*/
public Marshaller createMarshaller(String encoding) {
try {
Marshaller marshaller = jaxbContext.createMarshaller();
marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, Boolean.TRUE);
if (StringUtils.isNotBlank(encoding)) {
marshaller.setProperty(Marshaller.JAXB_ENCODING, encoding);
}
return marshaller;
} catch (JAXBException e) {
throw new RuntimeException(e);
}
}
/**
* 创建UnMarshaller
*/
public Unmarshaller createUnmarshaller() {
try {
return jaxbContext.createUnmarshaller();
} catch (JAXBException e) {
throw new RuntimeException(e);
}
}

/**
* 封装Root Element 是 Collection的情况.
*/

public static class CollectionWrapper {

@SuppressWarnings("unchecked")

@XmlAnyElement

protected Collection collection;

}

}

推荐文章