XML三种解析方式:

SAX解析:基于事件驱动,事件机制基于回调函数的,得到节点和节点之间内容时也会回调事件

PULL解析:相同基于事件驱动,仅仅只是回调时是常量

DOM解析:是先把XML文件装入内存中。在解析,耗费资源

SAX解析:

student.xml

-

-

张三

30

zhangsan@163.com

1900-09-09

组长

-

lisi

23

lisi@163.com

2000-09-09

组员

-

wangwu

30

wangwu@163.com

1990-09-09

组员

-

Jack

30

jack@163.com

2001-09-09

组长

-

Rose

23

rose@163.com

2003-09-09

组员

-

Tom

30

tom@163.com

2008-09-09

组长

StudentHandler.java

public class StudentHandler extends DefaultHandler {

// 声明成员变量

private List studentList; //存放多个学生

private Student student; //存放一个 学生

private String currentTag; //当前标签名字

// 给外部提供List集合的訪问方式

public List getList() {

return studentList;

}

// 重写5个回调方法

@Override

public void startDocument() throws SAXException {

// TODO Auto-generated method stub

super.startDocument();

System.out.println("文档解析開始");

}

/**

* String uri:元素的命名空间

* String localName:元素的本地名称

* String qName:标签的名称 book id name

* Attributes attributes: 属性的集合表示

*/

@Override

public void startElement(String uri, String localName, String qName,

Attributes attributes) throws SAXException {

super.startElement(uri, localName, qName, attributes);

//currentTag赋值

currentTag=qName;

//推断标签

if("students".equals(qName))

{

studentList=new ArrayList();

}

if("student".equals(qName))

{

student=new Student();

//推断属性

if(attributes.getLength()>0)

{

//获取属性的值

for (int i = 0; i < attributes.getLength(); i++) {

//获取key

String lname=attributes.getLocalName(i);

//通过推断获取值

if("id".equals(lname))

{

student.setId(Integer.parseInt(attributes.getValue(i))); //获取值

}else if("group".equals(lname))

{

student.setGroup(Integer.parseInt(attributes.getValue(i)));

}

}

}

}

}

/**

* char[] ch, 将開始与结尾标签之间的值转成char数组的形式

* int start, 数组開始位置

* int length 读取数据的长度

*/

@Override

public void characters(char[] ch, int start, int length)

throws SAXException {

super.characters(ch, start, length);

String str=new String(ch,start,length);

if("name".equals(currentTag))

{

student.setName(str);

}else if("sex".equals(currentTag))

{

student.setSex(str);

}else if("age".equals(currentTag))

{

student.setAge(Integer.parseInt(str));

}else if("email".equals(currentTag))

{

student.setEmail(str);

}else if("birthday".equals(currentTag))

{

student.setBirthday(str);

}else if("memo".equals(currentTag))

{

student.setMemo(str);

}

//清空currentTag

currentTag="";

}

@Override

public void endElement(String uri, String localName, String qName)

throws SAXException {

super.endElement(uri, localName, qName);

if("student".equals(qName))

{

studentList.add(student);

student=null;

}

}

@Override

public void endDocument() throws SAXException {

super.endDocument();

System.out.println("文档解析结束");

}

}

StudentTest.java

public class StudentTest {

/*

* @param args

* @throws Exception

*/

public static void main(String[] args) throws Exception {

// 1.创建解析工厂类

SAXParserFactory factory = SAXParserFactory.newInstance();

// 2.通过工厂对象创建一个解析器对象

SAXParser parser = factory.newSAXParser();

// 3.创建DefaultHandler的子类对象

StudentHandler handler = new StudentHandler();

parser.parse(new File("C:/1505/day30/xml/student.xml"), handler);

// 4.获取集合的结果

List list = handler.getList();

// 5.打印

for (Student student : list) {

System.out.println(student);

}

}

}

打印结果:

PULL解析:

pull解析的第三方的,须要导入jar包才干支持

本次依旧解析上面的student.xml文件

public class PullTest {

public static void main(String[] args) throws Exception {

// 1.创建解析工厂

XmlPullParserFactory factory = XmlPullParserFactory.newInstance();

// 2.通过解析工厂创建解析器的实例

XmlPullParser parser = factory.newPullParser();

// 3.给解析器设置要解析的数据

parser.setInput(new FileReader("C:/a/student.xml"));

// 4.创建集合对象 用于存储解析完毕之后的存放

List> list = null;

Map map = null;

// 5.获取事件类型

int eventType = parser.getEventType();

// 推断事件类型 不清楚循环次数使用while

while (eventType != XmlPullParser.END_DOCUMENT) {// 不是结尾就開始循环

// 获取当前标签名称

String cuTagString = parser.getName();

switch (eventType) {

case XmlPullParser.START_DOCUMENT:

list = new ArrayList>();

break;

case XmlPullParser.START_TAG:

if("student".equals(cuTagString)){

map = new HashMap();

//获取标签的属性值

for(int i=0;i

//获取第i个属性名

String name = parser.getAttributeName(i);

if("group".equals(name)){

map.put("group", parser.getAttributeValue(i));

}else if("id".equals(name)){

map.put("id", parser.getAttributeValue(i));

}

}

}else if("name".equals(cuTagString)){

map.put("name", parser.nextText());

}else if("sex".equals(cuTagString)){

map.put("sex", parser.nextText());

//..........这里不解析了

}

break;

case XmlPullParser.END_TAG:

if("student".equals(cuTagString)){

list.add(map);

}

cuTagString="";

break;

default:

break;

}

//获取下一个事件类型,此处忘记将会是一个死循环

eventType=parser.next();

}

for (Map map2 : list) {

System.out.println(map2);

}

}

}

打印结果:

常常出现PULL本地解析抛出:Exception in thread "main" org.xmlpull.v1.XmlPullParserException: PI must not start with xml (position:unknown 锘?@1:6 in java.io.FileReader@5e2de80c) 这里设置相应编码就能够。

以上两种都是本地解析,网络解析同理,仅仅要将解析的数据源设置相相应的网络流就能够。

查看原文