xmlpull是一个基于事件的xml解析框架,官网:http://www.xmlpull.org。
<dependency>
<groupId>xmlpull</groupId>
<artifactId>xmlpull</artifactId>
<version>1.1.3.1</version>
</dependency>
<!--需要引入kxml的依赖-->
<dependency>
<groupId>net.sf.kxml</groupId>
<artifactId>kxml2</artifactId>
<version>2.3.0</version>
</dependency>
XmlPullParserFactory factory = XmlPullParserFactory.newInstance();
factory.setNamespaceAware(true);
XmlPullParser xpp = factory.newPullParser();
xpp.setInput ( new StringReader ( "<foo>Hello World!</foo>" ) );
int eventType = xpp.getEventType();
while (eventType != xpp.END_DOCUMENT) {
if(eventType == xpp.START_DOCUMENT) {
System.out.println("Start document");
} else if(eventType == xpp.END_DOCUMENT) {
System.out.println("End document");
} else if(eventType == xpp.START_TAG) {
System.out.println("Start tag "+xpp.getName());
} else if(eventType == xpp.END_TAG) {
System.out.println("End tag "+xpp.getName());
} else if(eventType == xpp.TEXT) {
System.out.println("Text "+xpp.getText());
}
eventType = xpp.next();//需要手动调用,获取下一个事件类型
}
<classes>
<class name="1班">
<student name="张三"/>
<student name="李四"/>
</class>
<class name="2班">
<student name="王五"/>
<student name="赵六"/>
</class>
</classes>
public class Clazz{
private String name;
private List<Student> studentList;
...省略getter/setter
//向班级中添加一个学生
public void addStudent(Student student){
if(studentList == null){
studentList = new ArrayList<>();
}
studentList.add(student);
}
}
public class Student{
private String name;
...省略getter/setter
}
List<Clazz> clazzList = new ArrayList<>();//用list存储所有班级
Stack<Clazz> clazzStack = new Stack<>();//用栈存储当前解析的class
InputStream in = null;
try {
XmlPullParserFactory factory = XmlPullParserFactory.newInstance();
factory.setNamespaceAware(true);
XmlPullParser xpp = factory.newPullParser();
in = PacketXml.class.getResourceAsStream("/packet.xml");
xpp.setInput(in, "UTF-8");
int eventType = xpp.getEventType();
do {
if (eventType == XmlPullParser.START_TAG) {
String name = xpp.getName();
if (name.equals("class")){
Clazz clazz = new Clazz();
encapsulate(clazz, xpp);// 封装属性
}
if (name.equals("student")) {
Student student= new Student();
encapsulate(student, xpp);// 封装属性
clazzStack.peek().addStudent(student);
}
}
if (eventType == XmlPullParser.END_TAG) {
String name = xpp.getName();
if (name.equals("class")) {
clazzStack.pop();//当前class节点遍历结束,从栈中移除
}
}
eventType = xpp.next();
} while (eventType != XmlPullParser.END_DOCUMENT);
} catch (Exception e) {
e.printStackTrace();
} finally {
if (in != null){
try {
in.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
/**
* 利用反射实现xml属性到java bean属性的自动封装
*/
@SuppressWarnings({ "unchecked", "rawtypes" })
private static <T> void encapsulate(T t, XmlPullParser xpp) {
try {
int attributeCount = xpp.getAttributeCount();
Method getAttributeValue = XmlPullParser.class.getDeclaredMethod(
"getAttributeValue", String.class, String.class);
for (int i = 0; i < attributeCount; i++) {
String fieldName = xpp.getAttributeName(i);
String fieldVal = (String) getAttributeValue.invoke(xpp, null,
fieldName);
Class clazz = t.getClass();
Method setMethod = clazz.getDeclaredMethod(
"set" + fieldName.substring(0, 1).toUpperCase()
+ fieldName.substring(1), String.class);
setMethod.setAccessible(true);
setMethod.invoke(t, fieldVal);
}
} catch (Exception e) {
e.printStackTrace();
}
}