XML之JavaSE SAX解析
概述
SAX(Simple API For XML)是一个公共的基于事件的XML文档解析标准,能够通过一个简单的、快速的方法来对XML文档进行处理,和DOM相比它所占用的系统资源更少。
SAX既是一个接口,也是一个软件包。作为接口,SAX是事件驱动型XML解析的一个标准接口,对文档进行顺序扫描,当扫描到文档(document)开始、元素(element)开始与结束、文档(document)结束等地方时通知事件处理函数,由事件处理函数做相应动作,然后继续同样的扫描,直至文档结束。
SAX的优点:
解析速度快
占用内存少SAX的缺点:
无法知道当前解析标签(节点)的上层标签,及其嵌套结构,仅仅知道当前解析的标签的名字和属性,要知道其他信息需要程序猿自己编码
只能读取XML,无法修改XML
无法随机访问某个标签(节点)
SAX解析适用场合对于CPU资源宝贵的设备,如Android等移动设备
对于只需从xml读取信息而无需修改xml
1、获取到文档对象来操作XML文档
public static void main(String[] args){
//创建SAX解析工厂:利用抽象类SAXParserFactory中的静态方法进行实例化
SAXParserFactory factory = SAXParserFactory.newInstance();
//同过工厂创建解析器:调用抽象类SAXParserFactory的实例化对象的方法对抽象类SAXParser进行实例化
SAXParser parser = factory.newSAXParser();
//通过解析器解析XML文件,自动逐行解析
//uri为XML文档路径 String,dh为DefaultHandler实例化对象
//需根据续期对DefaultHandler类中的方法重写。
parser.parse(uri, dh); //Document创建完成,下文详细讲解
}
DefaultHandler类中主要的方法有,其中主要需要改写的方法有startElement,characters,endElement,通过对这3个方法的改写,即可完成XML文件的定向解析。
public void startDocument() throws SAXException {
}
public void startElement(String uri, String localName, String qName, Attributes attributes) throws SAXException {
//元素开始标签,可根据需求重写方法
}
public void characters(char[] ch, int start, int length) throws SAXException {
//文本内容,可根据需求重写方法
}
@Override
public void endElement(String uri, String localName, String qName) throws SAXException {
//元素结束标签,可根据需求重写方法
}
@Override
public void endDocument() throws SAXException {
}
2、打印XML文件中文本内容
public class Demo{
public Static void main(String[] args){
//创建SAX解析工厂:利用抽象类SAXParserFactory中的静态方法进行实例化
SAXParserFactory factory = SAXParserFactory.newInstance();
//同过工厂创建解析器:调用抽象类SAXParserFactory的实例化对象的方法对抽象类SAXParser进行实例化
SAXParser parser = factory.newSAXParser();
//通过解析器解析XML文件,自动逐行解析
//uri为XML文档路径 String,dh为DefaultHandler实例化对象
//需根据续期对DefaultHandler类中的方法重写。
//MyHandler类为创建的新类
parser.parse(uri, new MyHandler());
}
}
//创建一个类,继承DefaultHandler类并重写类中的方法
class MyHandler extends DefaultHandler{
@Override
public void startElement(String uri, String localName, String qName, Attributes attributes) throws SAXException {
//打印元素开始标签
System.out.print("<" + qName + ">");
}
@Override
public void characters(char[] ch, int start, int length) throws SAXException {
//打印文本内容
String string = new String(ch,start,length);
System.out.print(string);
}
@Override
public void endElement(String uri, String localName, String qName) throws SAXException {
//打印元素结束标签
System.out.print("</" + qName + ">");
}
}
3.通过输入元素名和元素索引得到元素内容
public class Demo{
public Static void main(String[] args){
//创建SAX解析工厂:利用抽象类SAXParserFactory中的静态方法进行实例化
SAXParserFactory factory = SAXParserFactory.newInstance();
//同过工厂创建解析器:调用抽象类SAXParserFactory的实例化对象的方法对抽象类SAXParser进行实例化
SAXParser parser = factory.newSAXParser();
//通过解析器解析XML文件,自动逐行解析
//uri为XML文档路径 String,dh为DefaultHandler实例化对象
//需根据续期对DefaultHandler类中的方法重写。
//MyHandler类为创建的新类
parser.parse(uri, new MyHandler(tagName,index));
}
}
class MyHandler extends DefaultHandler{
//定义内部索引i用于查找指定索引
private int i;
//定义索引index,需由外界传值
private int index;
//定义标志,在找到指定标签时对应文本内容使用
private boolean flag;
//标签名
private String tagName;
public MyHandler() {
}
//通过构造方法传递需要查找的标签内容和索引
public MyHandler(String tagName, int index) {
this.index = index;
this.tagName = tagName;
}
@Override
public void startElement(String uri, String localName, String qName, Attributes attributes) throws SAXException {
//对标签名配对,找到时将标志flag的值改为true
if(tagName!=null)
if(tagName.equals(qName)) {
flag = true;
}
}
@Override
public void characters(char[] ch, int start, int length) throws SAXException {
//标志flag与索引同时满足时,打印文本内容字符串,内部索引与输入索引值不相等时,跳过
if(flag && i==index) {
String string = new String(ch,start,length);
System.out.println(string);
}
}
@Override
public void endElement(String uri, String localName, String qName) throws SAXException {
//元素结束标签,将flag值改为false,内部索引加1
if(tagName!=null)
if(tagName.equals(qName)) {
flag = false;
i++;
}
}
}