概述
1.SAX解析
在使用DOM解析XML文档时,需要读取整个XML文档,在内存中构建整个DOM树的Document对象,从而再对XML文档进行操作。此种情况下,如果XML文档特别大,就会消耗计算机的大量内存,严重的情况下可能还会导致内存溢出。
SAX解析允许在读取文档的时候,即对文档进行处理,而不必等到整个文档装载完才对文档进行操作。
通过继承
DefaultHandler
,来开发一个SAX解析器
1.1.SAX解析机制
sax是一种推式的机制,你创建一个sax解析器,解析器在发现xml文档中的内容时就告诉你(把事件推给你,有点类似于java swing中的事件监听)。如何处理这些发现的内容,由程序员自己决定。
在基于sax的程序中,有五个最常用的sax事件:
1.2.SAX解析实例
依然使用DOM解析中用到的XML例子,如下:
<?xml version="1.0" encoding="utf-8" standalone="no"?><班级>
<学生 地址="香港">
<名字>周小星</名字>
<年龄>23</年龄>
<介绍>学习刻苦</介绍>
</学生>
<学生 地址="澳门">
<名字>林晓</名字>
<年龄>25</年龄>
<介绍>是一个好学生</介绍>
</学生></班级>
登录后复制
登录后复制
【步骤】:
1.使用SAXParserFactory创建SAX解析工厂
SAXParserFactory spf = SAXParserFactory.newInstance();
登录后复制
登录后复制
2.通过SAX解析工厂得到解析器对象
SAXParser sp = spf.newSAXParser();
登录后复制
登录后复制
3.将解析对象和事件处理器对象关联
sp.parse("src/myClass.xml",new MyHandler());
登录后复制
登录后复制
这里的MyHandler
需要自己定义,并且它要继承DefaultHandler
,然后在MyHandler
类中重写上文提到的5个sax事件方法,当然也可以只重写自己需要的。
比如现在我写的MyHandler
如下:
class MyHandler extends DefaultHandler{ /**
* 发现文档开始,该函数只会被调用一次
*/
@Override
public void startDocument() throws SAXException {
System.out.println("startDocument");
} /**
* 发现文档结束,该函数只会被调用一次
*/
@Override
public void endDocument() throws SAXException {
System.out.println("endDocument");
} /**
* 发现XML中的一个元素开始,会被反复调用
*/
@Override
public void startElement(String uri, String localName, String qName,
Attributes attributes) throws SAXException {
System.out.println("元素名称:"+qName);
} /**
* 发现XML中的一个元素结束,会被反复调用
*/
@Override
public void endElement(String uri, String localName, String qName)
throws SAXException {
} /**
* 发现XML文件中的文本,会被反复调用
*/
@Override
public void characters(char[] ch, int start, int length)
throws SAXException { // 显示文本内容
String text = new String(ch,start,length); if(!text.trim().equals("")){
System.out.println(text);
}
}
}
登录后复制
运行结果如下:
可以看到,这是对XML文档的一种遍历,而sax能够做的也只是遍历了。
那么,如果现在我们有这样一个需求:只显示所有学生的姓名和年龄,不显示学生的介绍,怎么实现呢?
我们可以在MyHandler
类中定义两个布尔变量isName和isAge,在startElement
方法中标识是否是姓名元素或者年龄元素,如果是的话才在characters
方法中获取对应的文本,如下:
1.定义两个布尔变量
private boolean isName = false;private boolean isAge = false;
登录后复制
登录后复制
2.在startElement
方法中添加判断
@Overridepublic void startElement(String uri, String localName, String qName,
Attributes attributes) throws SAXException { if(qName.equals("名字")){ this.isName = true;
}else if(qName.equals("年龄")){ this.isAge = true;
}
}
登录后复制
3.在characters
方法中根据标识符进行判断是否获取文本
@Overridepublic void characters(char[] ch, int start, int length) throws SAXException { // 显示文本内容
String text = new String(ch,start,length); if(!text.trim().equals("")&&(isName||isAge)){
System.out.println(text);
}
isName = false;
isAge = false;
}
登录后复制
登录后复制
最后要记得将两个布尔变量复位成false。
运行结果如下:
1.SAX解析
在使用DOM解析XML文档时,需要读取整个XML文档,在内存中构建整个DOM树的Document对象,从而再对XML文档进行操作。此种情况下,如果XML文档特别大,就会消耗计算机的大量内存,严重的情况下可能还会导致内存溢出。
SAX解析允许在读取文档的时候,即对文档进行处理,而不必等到整个文档装载完才对文档进行操作。
通过继承
DefaultHandler
,来开发一个SAX解析器
1.1.SAX解析机制
sax是一种推式的机制,你创建一个sax解析器,解析器在发现xml文档中的内容时就告诉你(把事件推给你,有点类似于java swing中的事件监听)。如何处理这些发现的内容,由程序员自己决定。
在基于sax的程序中,有五个最常用的sax事件:
1.2.SAX解析实例
依然使用DOM解析中用到的XML例子,如下:
<?xml version="1.0" encoding="utf-8" standalone="no"?><班级>
<学生 地址="香港">
<名字>周小星</名字>
<年龄>23</年龄>
<介绍>学习刻苦</介绍>
</学生>
<学生 地址="澳门">
<名字>林晓</名字>
<年龄>25</年龄>
<介绍>是一个好学生</介绍>
</学生></班级>
登录后复制
登录后复制
【步骤】:
1.使用SAXParserFactory创建SAX解析工厂
SAXParserFactory spf = SAXParserFactory.newInstance();
登录后复制
登录后复制
2.通过SAX解析工厂得到解析器对象
SAXParser sp = spf.newSAXParser();
登录后复制
登录后复制
3.将解析对象和事件处理器对象关联
sp.parse("src/myClass.xml",new MyHandler());
登录后复制
登录后复制
这里的MyHandler
需要自己定义,并且它要继承DefaultHandler
,然后在MyHandler
类中重写上文提到的5个sax事件方法,当然也可以只重写自己需要的。
比如现在我写的MyHandler
如下:
class MyHandler extends DefaultHandler{ /**
* 发现文档开始,该函数只会被调用一次
*/
@Override
public void startDocument() throws SAXException {
System.out.println("startDocument");
} /**
* 发现文档结束,该函数只会被调用一次
*/
@Override
public void endDocument() throws SAXException {
System.out.println("endDocument");
} /**
* 发现XML中的一个元素开始,会被反复调用
*/
@Override
public void startElement(String uri, String localName, String qName,
Attributes attributes) throws SAXException {
System.out.println("元素名称:"+qName);
} /**
* 发现XML中的一个元素结束,会被反复调用
*/
@Override
public void endElement(String uri, String localName, String qName)
throws SAXException {
} /**
* 发现XML文件中的文本,会被反复调用
*/
@Override
public void characters(char[] ch, int start, int length)
throws SAXException { // 显示文本内容
String text = new String(ch,start,length);
if(!text.trim().equals("")){
System.out.println(text);
}
}
}
登录后复制
运行结果如下:
可以看到,这是对XML文档的一种遍历,而sax能够做的也只是遍历了。
那么,如果现在我们有这样一个需求:只显示所有学生的姓名和年龄,不显示学生的介绍,怎么实现呢?
我们可以在MyHandler
类中定义两个布尔变量isName和isAge,在startElement
方法中标识是否是姓名元素或者年龄元素,如果是的话才在characters
方法中获取对应的文本,如下:
1.定义两个布尔变量
private boolean isName = false;private boolean isAge = false;
登录后复制
登录后复制
2.在startElement
方法中添加判断
@Overridepublic void startElement(String uri, String localName, String qName,
Attributes attributes) throws SAXException { if(qName.equals("名字")){
this.isName = true;
}else if(qName.equals("年龄")){ this.isAge = true;
}
}
登录后复制
3.在characters
方法中根据标识符进行判断是否获取文本
@Overridepublic void characters(char[] ch, int start, int length) throws SAXException { // 显示文本内容
String text = new String(ch,start,length); if(!text.trim().equals("")&&(isName||isAge)){
System.out.println(text);
}
isName = false;
isAge = false;
}
登录后复制
登录后复制
最后要记得将两个布尔变量复位成false。
运行结果如下:
以上就是XML—XML解析之SAX的内容,更多相关内容请关注靠谱客(www.uoften.com)!
最后
以上就是如意书本为你收集整理的XML—XML解析之SAX的全部内容,希望文章能够帮你解决XML—XML解析之SAX所遇到的程序开发问题。
如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。
发表评论 取消回复