-
在java中应用sax解析xml
添加时间:2013-5-3 点击量:在java中,原生解析xml文档的体式格式有两种,分别是:Dom解析和Sax解析
Dom解析功能强大,可增删改查,操纵时会将xml文档以文档对象的体式格式读取到内存中,是以实用于小文档
Sax解析是从头到尾逐行逐个元素读取内容,批改较为不便,但实用于只读的大文档
本文首要讲解Sax解析,其余放在后面
Sax采取事务驱动的体式格式解析文档。简单点说,如同在电影院看电影一样,从头到尾看一遍就完了,不克不及回退(Dom可交游返回读取)
在看电影的过程中,每碰到一个情节,一段泪水,一次擦肩,你都邑调动大脑和神经去接管或处理惩罚这些信息
同样,在Sax的解析过程中,读取到文档开首、结尾,元素的开首和结尾都邑触发一些回调办法,你可以在这些回调办法中进行响应事务处理惩罚
这四个办法是:startDocument() 、 endDocument()、 startElement()、 endElement
此外,光读取到节点处是不敷的,我们还须要characters()办法来细心处理惩罚元素内包含的内容
将这些回调办法凑集起来,便形成了一个类,这个类也就是我们须要的触发器
一般从Main办法中读取文档,却在触发器中处理惩罚文档,这就是所谓的事务驱动解析办法
如上图,在触发器中,起首开端读取文档,然后开端逐个解析元素,每个元素中的内容会返回到characters()办法
接着停止元素读取,所有元素读取完后,停止文档解析
如今我们开端创建触发器这个类,要创建这个类起首须要持续DefaultHandler
创建SaxHandler,并覆写响应办法:
import org.xml.sax.Attributes;
import org.xml.sax.SAXException;
import org.xml.sax.helpers.DefaultHandler;
public class SaxHandler extends DefaultHandler {
/ 此办法有三个参数
arg0是传回来的字符数组,其包含元素内容
arg1和arg2分别是数组的开端地位和停止地位 /
@Override
public void characters(char[] arg0, int arg1, int arg2) throws SAXException {
String content = new String(arg0, arg1, arg2);
System.out.println(content);
super.characters(arg0, arg1, arg2);
}
@Override
public void endDocument() throws SAXException {
System.out.println(\n…………停止解析文档…………);
super.endDocument();
}
/ arg0是名称空间
arg1是包含名称空间的标签,若是没有名称空间,则为空
arg2是不包含名称空间的标签 /
@Override
public void endElement(String arg0, String arg1, String arg2)
throws SAXException {
System.out.println(停止解析元素 + arg2);
super.endElement(arg0, arg1, arg2);
}
@Override
public void startDocument() throws SAXException {
System.out.println(…………开端解析文档…………\n);
super.startDocument();
}
/arg0是名称空间
arg1是包含名称空间的标签,若是没有名称空间,则为空
arg2是不包含名称空间的标签
arg3很明显是属性的凑集 /
@Override
public void startElement(String arg0, String arg1, String arg2,
Attributes arg3) throws SAXException {
System.out.println(开端解析元素 + arg2);
if (arg3 != null) {
for (int i = 0; i < arg3.getLength(); i++) {
// getQName()是获取属性名称,
System.out.print(arg3.getQName(i) + =\ + arg3.getValue(i) + \);
}
}
System.out.print(arg2 + :);
super.startElement(arg0, arg1, arg2, arg3);
}
}XML文档:
<?xml version=1.0 encoding=UTF-8?>
<books>
<book id=001>
<title>Harry Potter</title>
<author>J K. Rowling</author>
</book>
<book id=002>
<title>Learning XML</title>
<author>Erik T. Ray</author>
</book>
</books>TestDemo测试类:
import java.io.File;
import javax.xml.parsers.SAXParser;
import javax.xml.parsers.SAXParserFactory;
public class TestDemo {
public static void main(String[] args) throws Exception {
// 1.实例化SAXParserFactory对象
SAXParserFactory factory = SAXParserFactory.newInstance();
// 2.创建解析器
SAXParser parser = factory.newSAXParser();
// 3.获取须要解析的文档,生成解析器,最后解析文档
File f = new File(books.xml);
SaxHandler dh = new SaxHandler();
parser.parse(f, dh);
}
}输出成果:
…………开端解析文档…………
开端解析元素 books
books:
开端解析元素 book
id=001book:
开端解析元素 title
title:Harry Potter
停止解析元素 title
开端解析元素 author
author:J K. Rowling
停止解析元素 author
停止解析元素 book
开端解析元素 book
id=002book:
开端解析元素 title
title:Learning XML
停止解析元素 title
开端解析元素 author
author:Erik T. Ray
停止解析元素 author
停止解析元素 book
停止解析元素 books
…………停止解析文档…………
上方的固然正确显示了履行流程,然则输出却很乱
为了加倍清楚的履行此流程,我们还可以重写SaxHandler,使其将本来的xml文档还原一遍
重写的SaxHandler类:
import org.xml.sax.Attributes;
import org.xml.sax.SAXException;
import org.xml.sax.helpers.DefaultHandler;
public class SaxHandler extends DefaultHandler {
@Override
public void characters(char[] arg0, int arg1, int arg2) throws SAXException {
System.out.print(new String(arg0, arg1, arg2));
super.characters(arg0, arg1, arg2);
}
@Override
public void endDocument() throws SAXException {
System.out.println(\n停止解析);
super.endDocument();
}
@Override
public void endElement(String arg0, String arg1, String arg2)
throws SAXException {
System.out.print(</);
System.out.print(arg2);
System.out.print(>);
super.endElement(arg0, arg1, arg2);
}
@Override
public void startDocument() throws SAXException {
System.out.println(开端解析);
String s = <?xml version=\1.0\ encoding=\UTF-8\?>;
System.out.println(s);
super.startDocument();
}
@Override
public void startElement(String arg0, String arg1, String arg2,
Attributes arg3) throws SAXException {
System.out.print(<);
System.out.print(arg2);
if (arg3 != null) {
for (int i = 0; i < arg3.getLength(); i++) {
System.out.print( + arg3.getQName(i) + =\ + arg3.getValue(i) + \);
}
}
System.out.print(>);
super.startElement(arg0, arg1, arg2, arg3);
}
}履行成果:
如今看起来很多多少了,将其还原更能充沛申明其解析流程
我们永远不要期待别人的拯救,只有自己才能升华自己。自己已准备好了多少容量,方能吸引对等的人与我们相遇,否则再美好的人出现、再动人的事情降临身边,我们也没有能量去理解与珍惜,终将擦肩而过。—— 姚谦《品味》