在上一篇中[url]http://gaofulai1988.iteye.com/blog/2262673[/url],主要讲解了DOM解析xml,它最大的不足之处是要在解析之前要载入这个XML文件,如果这个文件很大,它的效率就不高了。后来有人提出了基于标签事件触发的方式来解析XML文件。什么意思呢?
如果遇到一个<,那么它是一个标签的开始,如果遇到/>那么它是一个标签的结束。这些特殊标志出现的时候,就会触发一个事件来处理。
还是之前的那个XML。
代码如下:
上面加了一个特殊的输出,主要是为了看方法触发的先后情况。不管是startElement还是endElement,它们之后都会调用characters()这个方法,所以为什么要在endElement中将tag置空的原因。
如果遇到一个<,那么它是一个标签的开始,如果遇到/>那么它是一个标签的结束。这些特殊标志出现的时候,就会触发一个事件来处理。
还是之前的那个XML。
<?xml version="1.0" encoding="UTF-8"?>
<Students>
<student>
<NO id="123">123456</NO>
<NAME>abc</NAME>
</student>
<student>
<NO id="234">456789</NO>
<NAME>def</NAME>
</student>
</Students>
代码如下:
public class SAXDemo extends DefaultHandler {
String tag;
public static void main(String args[]) {
try {
SAXParserFactory sf = SAXParserFactory.newInstance();
SAXParser sp = sf.newSAXParser();
SAXDemo reader = new SAXDemo();
sp.parse(new InputSource("D:" + File.separator + "test.xml"),
reader);
} catch (Exception e) {
e.printStackTrace();
}
}
// 处理标签的值
@Override
public void characters(char ch[], int start, int length)
throws SAXException {
System.out.println("outprint value");
if (tag.equals("NO")) {
System.out.print("\tNO:" + new String(ch, start, length));
}
if (tag.equals("NAME")) {
System.out.println("\tNAME:" + new String(ch, start, length));
}
}
// 一定要写这个end方法,并且重新赋值
// 遇到/> 就会触发这个方法
@Override
public void endElement(String uri, String localName, String qName)
throws SAXException {
System.out.println("2."+qName);
tag = "";
};
// 遇到 "<" 就会触发这个方法,qName就是标签名,Attributes是标签的属性
@Override
public void startElement(String uri, String localName, String qName,
Attributes attrs) {
System.out.println("1."+qName);
if (qName.equals("NO")) {
// 输出属性的值
System.out.print("id:" + attrs.getValue(0));
}
this.tag = qName;
}
}
上面加了一个特殊的输出,主要是为了看方法触发的先后情况。不管是startElement还是endElement,它们之后都会调用characters()这个方法,所以为什么要在endElement中将tag置空的原因。