解析XML专题之SAX方式

解析XML专题之SAX方式

 

SAX和DOM解析的不同原理

DOM解析: 是一次性加载文件所有内容到内存中,并构建一个驻留在内存的树状结构(节点数),如果需要解析的xml文档过大,或我们只需要对文档部分内容感兴趣,会引起性能问题

 

SAX解析: 是逐行扫描文档,一边扫描,一边解析。

与DOM相比, SAX方法更快速,更有效,可以在解析的任何时刻停止解析,但是它的缺点就是实现太复杂。

 

SAX实现步骤

  • 首先SAXParseFactory 来创建一个SAXParserFactory实例

SAXParserFactory factory = SAXParserFactory.newInstance();

  • 根据SAXParserFactory实例来创建SAXParser

SAXParserHandler hanlder = new SAXParserHandler();

parser.parse("test.xml", hanlder);

 

在入口代码处如下:

                // 获取SAXParserFactory实例
		SAXParserFactory factory = SAXParserFactory.newInstance();
		// 获取SAXParser 实例
		SAXParser parser;
		try {
			parser = factory.newSAXParser();
			SAXParserHandler hanlder = new SAXParserHandler();
			parser.parse("test.xml", hanlder);
		} catch (SAXException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		} catch (ParserConfigurationException e1) {
			e1.printStackTrace();
		}
  • 在解析过程中触发相对于接口中的事件处理程序

创建自定义Handler类继承DefaultHanlder, 通过下面的方法重写来进行事件处理

如下代码所示:

public class SAXParserHandler extends DefaultHandler {
      int studentsIndex=0;
	/*
	 * 当遇到开始标记时调用
	 * qName 表示扫描的开始标记的名字
	 */
	@Override
	public void startElement(String uri, String localName, String qName, Attributes attributes) throws SAXException {
		super.startElement(uri, localName, qName, attributes);
		if(qName.equals("student")) {
			studentsIndex++ ;
			System.out.println("开始遍历 第 "+studentsIndex + "个 student ");
			//已知student标记下的属性个数以及属性名,可以通过如下方法获取属性值
			String value = attributes.getValue("id");
			System.out.println("开始标记 " + qName + "的属性值" + value);
			
			//如果不确定属性个数和属性名,采用下面的方法来遍历
			int num = attributes.getLength();
			for(int i = 0 ; i < num ; i++) {
				System.out.print("开始遍历第" + (i + 1 ) + "个属性 : " + attributes.getQName(i) );
				System.out.println(" = " + attributes.getValue(i));
			}
		}else {
			System.out.print ("节点名:"+qName);
		}
		
		
	}
	
	
	/*
	 * 获取节点值的方法 (当分析器遇到无法识别为标记或者指令类型字符时调用)
	 * ch所有文档内容除了节点之外
	 */
	
	@Override
	public void characters(char[] ch, int start, int length) throws SAXException {
		super.characters(ch, start, length);
		String value = new String(ch, start, length);
		if(!value.trim().equals("")) {
			System.out.println(" = " + value);
		}
		
		
	}



	/*
	 * 当遇到节点结束时调用
	 */
	@Override
	public void endElement(String uri, String localName, String qName) throws SAXException {
		// TODO Auto-generated method stub
		super.endElement(uri, localName, qName);
		if(qName .equals("student")) {
			System.out.println("--------------------结束扫描标记第" + studentsIndex +" student-----------------");
		}
		
	}
	
	/*
	 * 文件打开时调用
	 */
	@Override
	public void startDocument() throws SAXException {
		// TODO Auto-generated method stub
		super.startDocument();
		System.out.println("xml文档解析开始");
	}
	
	/*
	 * 当到文档的末尾调用
	 */
	@Override
	public void endDocument() throws SAXException {
		// TODO Auto-generated method stub
		super.endDocument();
		System.out.println("xml文档解析结束");
	}
	
}

运行结果如下:
 

xml文档解析开始
节点名:students开始遍历 第 1个 student 
开始标记 student的属性值1
开始遍历第1个属性 : id = 1
节点名:name = zhangsan
节点名:age = 20
--------------------结束扫描标记第1 student-----------------
开始遍历 第 2个 student 
开始标记 student的属性值2
开始遍历第1个属性 : id = 2
节点名:name = lisi
节点名:age = 25
--------------------结束扫描标记第2 student-----------------
xml文档解析结束

 

你可能感兴趣的:(Java)