XML
文档声明<?xml version="1.0" encoding="utf-8"?>
基本和HTML一样,注意下面一条。
标签区分大小写
解析方式
DOM Document Object Model 文档对象模型
核心思想: 把文档中所有内容都 封装成对象。
对象种类:
Document 整个(HTML,XML)文档
Element 文档中每一个标签都会被封装成Element对象
Attribute 标签上的每一个属性都会被封装成Attribute
Text 文档中,标签内的文本都会封装成Text对象
Common 注释,文档中的注释 ,会被封装成common.
- Dom的优势:将文档结构(所有内容)都以对象的形式保留在了内存中。我们可以对内存中的(Dom树)进行增删改查操作并且操作很方便。
- Dom的劣势:因为保留了全部文档内容,资源消耗比较大。
SAX解析思想
在读取xml文档时, 已经根据定义好的事件,对xml内容进行了筛选.解析完成后,内存中只保留了我们想要的内容。比较节约资源.。在资源比较匮乏的平台使用,比如手机。
缺点: 没有保留文档的结构, 无法进行增删改的操作。只能查询。
文档开始事件: startDocument
文档结束事件: endDocument
元素开始事件: startElement
元素结束事件: endElement
文本事件: character
Pull解析
与Sax一样,都属于事件驱动的解析方式,相比Sax解析过程更加灵活。
SAX一旦开始解析就是从头读到尾,不解析完整个文档不会停.
pull解析较为灵活,是以事件为单位,手动向下继续.。如果获得到我们要找的内容,可以停止继续解析。
一个小例子,从本地读取xml文件,并采用Pull方式解析。这里用到kxml2-2.3.0.jar
package xml;
import java.util.*;
public class Student {
private String id;
private String name;
private String sex;
private String age;
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getSex() {
return sex;
}
public void setSex(String sex) {
this.sex = sex;
}
public String getAge() {
return age;
}
public void setAge(String age) {
this.age = age;
}
// 重写方法,方便打印
@Override
public String toString() {
return "{id=" + id + ", name=" + name + ", sex=" +sex + ", age=" + age +"}";
}
}
package xml;
import org.xmlpull.v1.XmlPullParser;
import org.xmlpull.v1.XmlPullParserException;
import org.xmlpull.v1.XmlPullParserFactory;
import java.io.*;
import java.util.ArrayList;
import java.util.List;
public class PullTool {
// 使用Pull解析
public static List<Student> parseXml(Reader xmlData) throws XmlPullParserException, IOException {
List<Student> students = null;
Student stu = null;
// 创建解析器工厂
XmlPullParserFactory factory = XmlPullParserFactory.newInstance();
// 使用工厂获得解析器
XmlPullParser xmlPullParser = factory.newPullParser();
// 使用解析器读取xml流
xmlPullParser.setInput(xmlData);
// 获得事件状态
int type = xmlPullParser.getEventType();
// 判断是否到达文档结尾
while (type != XmlPullParser.END_DOCUMENT) {
String nodeName = xmlPullParser.getName();
switch (type) {
case XmlPullParser.START_TAG:
// 发现students标签就新建列表
if ("students".equals(nodeName)) {
students = new ArrayList<>();
// 发现srudent标签就new一个学生
} else if ("student".equals(nodeName)) {
stu = new Student();
// student标签有且有一个id属性,填入0就好
String id = xmlPullParser.getAttributeName(0);
stu.setId(id);
} else if ("stuname".equals(nodeName)) {
// 指针指向的是stuname标签,要获取文本,需要将指针移动到下一个文本数据
String stuname = xmlPullParser.nextText();
stu.setName(stuname);
} else if ("sex".equals(nodeName)) {
String sex = xmlPullParser.nextText();
stu.setName(sex);
} else if ("age".equals(nodeName)) {
String age = xmlPullParser.nextText();
stu.setName(age);
}
break;
// 标签尾
case XmlPullParser.END_TAG:
if ("student".equals(nodeName)) {
students.add(stu);
stu = null;
}
break;
default:
}
// 指向下一行后返回当前状态
type = xmlPullParser.next();
}
return students;
}
public static void main(String[] args) throws Exception {
BufferedReader reader = new BufferedReader(new FileReader("src/xml/stu.xml"));
List<Student> students = parseXml(reader);
Student aa = new Student();
aa.setId("1");
aa.setName("Tom");
aa.setAge("18");
aa.setSex("male");
System.out.println(aa); // 打印{id=1, name=Tom, sex=male, age=18}
}
}
2017.3.13
by @sunhaiyu