xml--通过SAX解析XML

    SAX的全称是Simple APIs for XML,也即XML简单应用程序接口。与DOM不同,SAX提供的访问模式是一种顺序模式,这是一种快速读写XML数据的方式。当使用SAX分析器对XML文档进行分析时,会触发一系列事件,并激活相应的事件处理函数,应用程序通过这些事件处理函数实现对XML文档的访问,因而SAX接口也被称作事件驱动接口。
    SAX分析器在对XML文档进行分析时,触发了一系列的事件,由于事件触发本身是有时序性的,因此,SAX提供的是一种顺序访问机制,对于已经分析过的部分,不能再倒回去重新处理。SAX之所以被叫做"简单"应用程序接口,是因为SAX分析器只做了一些简单的工作,大部分工作还要由应用程序自己去做。也就是说,SAX分析器在实现时,它只是顺序地检查XML文档中的字节流,判断当前字节是XML语法中的哪一部分、是否符合XML语法,然后再触发相应的事件,而事件处理函数本身则要由应用程序自己来实现。同DOM分析器相比,SAX分析器缺乏灵活性。然而,由于SAX分析器实现简单,对内存要求比较低,因此实现效率比较高,对于那些只需要访问XML文档中的数据而不对文档进行更改的应用程序来说,SAX分析器更为合适。

例子:

使用SAX开始几步和DOM使用方式一致,

SAXParserFactory factory = SAXParserFactory.newInstance();
SAXParser parser = factory.newSAXParser();

在第23行MyHandler2类中,我们看到有3个方法,startElement、characters、endElement,这三个方法是jdk中DefaultHandler的接口的实现。

package com.sax;

import java.io.File;
import java.util.Stack;

import javax.xml.parsers.SAXParser;
import javax.xml.parsers.SAXParserFactory;

import org.xml.sax.Attributes;
import org.xml.sax.SAXException;
import org.xml.sax.helpers.DefaultHandler;

public class SaxTest2 {
	public static void main(String[] args) throws Exception {
		SAXParserFactory factory = SAXParserFactory.newInstance();

		SAXParser parser = factory.newSAXParser();

		parser.parse(new File("student.xml"), new MyHandler2());
	}
}

class MyHandler2 extends DefaultHandler {
	private Stack<String> stack = new Stack<String>();

	private String name;

	private String gender;

	private String age;
	
	private String pre;

	@Override
	public void startElement(String uri, String localName, String qName,
			Attributes attributes) throws SAXException {
//		stack.push(qName);
		pre = qName;

		for (int i = 0; i < attributes.getLength(); i++) {
			String attrName = attributes.getQName(i);
			String attrValue = attributes.getValue(i);

			System.out.println(attrName + " = " + attrValue);
		}
	}

	@Override
	public void characters(char[] ch, int start, int length)
			throws SAXException {
//		String tag = stack.peek();
		String tag = pre;

		if ("姓名".equals(tag)) {
			name = new String(ch, start, length);
		} else if ("性别".equals(tag)) {
			gender = new String(ch, start, length);
		} else if ("年龄".equals(tag)) {
			age = new String(ch, start, length);
		}
	}

	@Override
	public void endElement(String uri, String localName, String qName)
			throws SAXException {
		//stack.pop(); // 表示该元素已经解析完毕,需要从栈中弹出

		if ("学生".equals(qName)) {
			System.out.println("姓名:" + name);
			System.out.println("性别:" + gender);
			System.out.println("年龄:" + age);

			System.out.println();
		}
		pre = null;
	}
}


3个方法通过图片描述如下,标签开始、标签中间内容、标签结束,其他以此类推,外面的“学生”标签规则也都一直。

其中qname这个参数指xml中每个元素头的名字,详见截图。

attributes参数含义,详见截图。

具体的方法含义详见JDK,其中还包含好多其他方法,我们可以依需求进行实现。

附:

xml文件

<?xml version="1.0" encoding="utf-8"?>
<学生名册 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="student.xsd" >
	<学生 学号="1">
		<姓名>张三</姓名>
		<性别>男</性别>
		<年龄>20</年龄>
	</学生>
	<学生 学号="2">
		<姓名>李四</姓名>
		<性别>女</性别>
		<年龄>19</年龄>
	</学生>
	<学生 学号="3">
		<姓名>王五</姓名>
		<性别>男</性别>
		<年龄>21</年龄>
	</学生>
</学生名册>

输出结果

xmlns:xsi = http://www.w3.org/2001/XMLSchema-instance
xsi:noNamespaceSchemaLocation = student.xsd
学号 = 1
姓名:张三
性别:男
年龄:20

学号 = 2
姓名:李四
性别:女
年龄:19

学号 = 3
姓名:王五
性别:男
年龄:21

注意:

截图中,该行全局变量在此方法结束后需要清空,因为是全局变量如果不清空,会影响程序后续执行,可以尝试注掉该行代码试试。


原文地址:https://www.cnblogs.com/keanuyaoo/p/3266488.html