260 likes | 388 Views
第 7 章 SAX 事件基础的 XML 解析. 7-1 SAX 2 的基础 7-2 JAXP 的 SAX API 7-3 Java 语言建立 SAX 应用程序 7-4 SAX 的 XML 文件解析 7-5 SAX 的 XML 文件验证. 7-1 SAX 2 的基础. 7-1-1 SAX 2 是什么 7-1-2 DOM 和 SAX 的差异 7-1-3 SAX 的优缺点. 7-1-1 SAX 2 是什么 - 说明.
E N D
第7章 SAX事件基础的XML解析 • 7-1 SAX 2的基础 • 7-2 JAXP的SAX API • 7-3 Java语言建立SAX应用程序 • 7-4 SAX的XML文件解析 • 7-5 SAX的XML文件验证
7-1 SAX 2的基础 • 7-1-1 SAX 2是什么 • 7-1-2 DOM和SAX的差异 • 7-1-3 SAX的优缺点
7-1-1 SAX 2是什么-说明 • SAX是另一种解析XML文件的技术,使用事件基础來处理XML文件,目前大部分XML解析器除了支持DOM外,都会一并支持SAX解析,SAX 1.0版是在1998年5月推出。 • SAX 2全名是Simple API for XML version 2,这是SAX在2000年5月推出的新版本。SAX是一组程序接口,可以将XML文件视为字符串流的文档,在读取XML元素时触发一系列事件,只需编写所需的事件处理程序,就可以分析或取得XML元素。
7-1-1 SAX 2是什么-图例 • XML文件在经过解析文件后,SAX解析器产生一系列事件,我们可以建立事件处理程序來处理这些事件。
7-1-2 DOM和SAX的差异-范例文件 • DOM和SAX的差异在于SAX解析是一种只读、只能向前读取;DOM則是完整读入XML文件來建立树状结构,以便可以隨时浏览和更新节点文档,换句话说,DOM比SAX需要更多的系统资源。 • 接下來,我们就比较DOM和SAX解析XML文件的差异,使用的XML文件范例,如下所示: <hello> <message>大家好!</message> <message>Say Hello!</message> </hello>
7-1-2 DOM和SAX的差异-DOM如何解析XML文件 • DOM解析XML文件建立Document物件后,就是建立一棵树状结构的节点,如下图所示:
7-1-2 DOM和SAX的差异-SAX如何解析XML文件1 • 若使用SAX载入XML文件,如同使用程序开启一個「顺序文档」(Sequential File),可以将XML元素和內容视为文字文档的內容來读取,当读到XML元素的开始标签、结尾标签和內容时,就依序产生一系列的事件,如下所示: • startDocument • startElement • Characters • endElement • endDocument
7-1-2 DOM和SAX的差异-SAX如何解析XML文件2 • 以前述XML文件为例,SAX读入的文档如同字符串流,如下所示: {<hello>} {<message>} {大家好!} {</message>} {<message>} {Say Hello!} {</message>} {</hello>} • 顺序读取的文档为「{}」括起的根元素、子元素和元素內容,XML解析器在读取时,就会依序产生上述事件,换句话说,我们只需编写对应的事件处理程序,就可以使用SAX來处理XML文件。
7-1-3 SAX的优缺点-SAX的优点 • SAX使用比较有效率:因为SAX不会将XML文件完全载入内存,所以任何尺寸的XML文件都可以解析;DOM技术需要将整份XML文件载入内存來建立树状结构,对于大尺寸的XML文件,就需要庞大的内存空间。 • SAX使用容易:XML应用程序如果只需部分XML元素,此时,SAX在使用上将更加容易。因为SAX并不用如同DOM一般,将整份XML文件载入内存。 • SAX速度快:SAX应用程序只是順序读取XML文件的內容,而沒有建立树状结构,所以,SAX将比DOM更加有效率。
7-1-3 SAX的优缺点-SAX的缺点 • SAX只能读取XML內容:SAX只能遍历XML文件來读取XML元素,并不能更改XML文件的內容;不同于DOM接口能夠轻易读写XML文件的內容。 • SAX无法隨机存取XML元素:SAX技术有如读取文字文档內容,XML元素是一個接著一個XML元素以順序方式來读取XML元素,而且无法回頭;不同于DOM将XML文件视为一個树状结构,可以隨机取得指定XML元素的文档。
7-2 JAXP的SAX API-说明 • JAXP API的SAX API(Simple API for XML API)是使用javax.xml.parsers组件包的SAXParserFactory类來取得SAXParser实例,以便解析XML文件來产生一系列的事件,如下图所示:
7-3 Java语言建立SAX应用程序-引用组件包 • 在Java程序建立SAX应用程序需要先引用JAXP API的相关组件包,如下所示: import javax.xml.parsers.*; import org.xml.sax.*; import org.xml.sax.helpers.*; • 程序代码在引用SAX所需的API组件包后,Java程序需要实作ContentHandler、ErrorHandler、DTDHandler和EntityResolver接口來建立SAX应用程序。
7-3 Java语言建立SAX应用程序-继承DefaultHandler类別 public class Ch7_3 extends DefaultHandler { public void startDocument() throws SAXException { } public void startElement(String namespaceURI, String localName, String qName, Attributes atts ) throws SAXException { } public void characters(char buf[], int offset, int len) throws SAXException { } public void endElement(String namespaceURI, String localName,String qName) throws SAXException { } public void endDocument() throws SAXException { } ……... }
7-3 Java语言建立SAX应用程序- ContentHandler接口的方法 • 在ContentHandler接口的主要方法说明,如下表所示:
7-3 Java语言建立SAX应用程序-使用SAX解析XML文件 • 在Java主程序取得SAXParserFactory物件后,就可以建立SAXParser物件來解析XML文件,如下所示: SAXParserFactory spf = SAXParserFactory.newInstance(); spf.setValidating(true); spf.setNamespaceAware(false); • 接著建立SAXParser物件來執行XML解析,如下所示: SAXParser sp = spf.newSAXParser(); sp.parse(new File(filename), new Ch7_3());
7-4 SAX的XML文件解析 • 在上一节的程序范例是直接在Java主程序的Ch7_3类別继承DefaultHandler类別,在这一节里我们可以建立独立的MyHandler类來继承DefaultHandler类,如下所示: class MyHandler extends DefaultHandler { ……… } • 类覆盖ContentHandler接口方法startDocument()、startElement()、characters()、endElement()和endDocument()方法來处理XML文件。
7-5 SAX的XML文件验证 • 7-5-1 SAX的DTD验证 • 7-5-2 SAX的Schema验证
7-5-1 SAX的DTD验证-说明 • DTD原來是SGML的语法检查,XML 1.0版支持DTD验证方式,DTD定义的规則可以帮助XML解析器检查XML文件的內容。 • 在JAXP的SAX API支持DTD验证,当XML文件指定DTD文档,在XML解析器载入XML文件时,就可以进行XML文件內容的验证。
7-5-1 SAX的DTD验证-错误处理类別 • 在解析XML文件前,我们需要指定SAXParser物件的错误处理來取得解析错误的相关资信,如下所示: SAXParser sp = spf.newSAXParser(); sp.parse(new File(filename), new MyHandler()); • 程序代码指定错误处理是MyHandler类別的物件。
7-5-1 SAX的DTD验证-MyHandler类別宣告1 private static class MyHandler extends DefaultHandler { private String getMsg(SAXParseException spe) { String sysId = spe.getSystemId(); if ( sysId == null ) sysId = "NULL"; String msg = "\n文档: " + sysId + "\n行号: " + spe.getLineNumber() + "\n信息: "+ spe.getMessage(); return msg; }
7-5-1 SAX的DTD验证-MyHandler类別宣告2 public void warning(SAXParseException spe) throws SAXException { System.out.println("警告: " + getMsg(spe)); } public void error(SAXParseException spe) throws SAXException { String message = "错误: " + getMsg(spe); throw new SAXException(message); } public void fatalError(SAXParseException spe) throws SAXException { String message = "严重错误: " + getMsg(spe); throw new SAXException(message); } }
7-5-1 SAX的DTD验证-使用DTD验证 • 在SAXParserFactory物件只需使用setValidating()方法设定參数,即可决定是否验证XML文件,如下所示: SAXParserFactory spf = SAXParserFactory.newInstance(); spf.setValidating(true); • 參数true表示XML解析器需要验证XML文件,预设是DTD验证;如果设为false,解析器就不会进行文件的验证。
7-5-2 SAX的Schema验证-1 • XML Schema是W3C的标准规范,XML Schema拥有很高的扩充性,可以直接扩充別人現成定义的XML Schema來验证XML文件。 • JAXP API的SAX也支持XML Schema验证,我们只需使用setProperty()方法设定解析器參数來支持Schema验证,如下所示: sp.setProperty(JAXP_SCHEMA_LANGUAGE, W3C_XML_SCHEMA); sp.setProperty(JAXP_SCHEMA_SOURCE, schema);
7-5-2 SAX的Schema验证-2 • 在SAXParserFactory物件只需设定相关參数,就可以使用XML Schema來验证XML文件,如下所示: SAXParserFactory spf = SAXParserFactory.newInstance(); spf.setValidating(true); spf.setNamespaceAware(true); • 方法分別指定解析器支持名称空间和XML文件验证。