博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
在java中使用sax解析xml
阅读量:6420 次
发布时间:2019-06-23

本文共 4357 字,大约阅读时间需要 14 分钟。

在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文档:

Harry Potter
J K. Rowling
Learning XML
Erik T. Ray

 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);	}}

 输出结果:

…………开始解析文档…………开始解析元素 booksbooks:    开始解析元素 bookid="001"book:       开始解析元素 titletitle:Harry Potter结束解析元素  title       开始解析元素 authorauthor:J K. Rowling结束解析元素  author    结束解析元素  book    开始解析元素 bookid="002"book:       开始解析元素 titletitle:Learning XML结束解析元素  title       开始解析元素 authorauthor: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("
"); super.endElement(arg0, arg1, arg2); } @Override public void startDocument() throws SAXException { System.out.println("开始解析"); String s = "
"; 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); }}

 执行结果:

现在看起来好多了,将其还原更能充分说明其解析流程

 

 

 

 

转载地址:http://vclra.baihongyu.com/

你可能感兴趣的文章
MHA配置参数
查看>>
深入理解Lock
查看>>
vim的块选择
查看>>
HTML --块
查看>>
在DLL中获取主进程窗口句柄
查看>>
基于消息队列的双向通信
查看>>
一个不错的loading效果
查看>>
Debian允许root用户登录
查看>>
linux的文件系统
查看>>
上云利器,K8S应用编排设计器之快到极致
查看>>
袋鼠云服务案例系列 | 从DB2到MySQL,某传统金融平台的互联网转型之路
查看>>
RealServer配置脚本
查看>>
九月份技术指标 华为交换机的简单配置
查看>>
python 写json格式字符串到文件
查看>>
分布式文件系统MogileFS
查看>>
电力线通信载波模块
查看>>
linux vim详解
查看>>
Java23种设计模式案例:策略模式(strategy)
查看>>
XML解析之DOM4J
查看>>
图解微服务架构演进
查看>>