java中使用sax解析xml的解决方法
程序员文章站
2023-12-15 19:38:40
在java中,原生解析xml文档的方式有两种,分别是:dom解析和sax解析
dom解析功能强大,可增删改查,操作时会将xml文档以文档对象的方式读取到内存中,因此适用于...
在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="001"book:
开始解析元素 title
title:harry potter
结束解析元素 title
开始解析元素 author
author:j k. rowling
结束解析元素 author
结束解析元素 book
开始解析元素 book
id="002"book:
开始解析元素 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);
}
}
执行结果:
现在看起来好多了,将其还原更能充分说明其解析流程