zoukankan      html  css  js  c++  java
  • 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
    
    

    注意:

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


  • 相关阅读:
    Linux基础命令(一)
    You've made choice
    protege推理
    字符编码
    第二次作业
    数据类型-集合set
    数据类型-元组&字典
    数据类型-列表
    数据类型-数值&字符串
    流程控制之for循环
  • 原文地址:https://www.cnblogs.com/keanuyaoo/p/3266488.html
Copyright © 2011-2022 走看看