上一文中总结了dom解析xml文档的方式,本文开始总结使用SAX解析xml 的方式及它的优缺点!
SAX(Simple API for XML),是指一种接口,或者一个软件包.
首先我们应该知道SAX解析和dom解析的区别:
dom是树结构解析,易于理解和开发,它可以随意访问文件所在的节点位置,易于修改,删除和查询。但对于dom文档过大时,则会解析较慢。
而SAX解析是事件推动型,顺序读取文件的节点,且只能读取文档的内容,不能对文档的内容进行修噶,对文档的大小没有过多的限制,但开大复杂度较高,
下面介绍一个SAX解析xml文档的几个关键步骤:
(1)、创建XML解析处理器,即SAXParseFactory 的实例,
SAXParserFactory factory = SAXParserFactory.newInstance();
(2)、通过factory创建SAX解析器
SAXParser parser = factory.newSAXParser();
(3)、通过SAXParse 的实例,创建xml解析处理器。对文档进行解析,
parser.parse(uri,handler) 方法有两个参数uri , handler对象,uri就是我们的文档的路径,
接下来我们需要创建一个handler对象,我们创建一个Myhandler类,这个Myhandler类需要继承DefaultHandler类,
Myhandler handler = new Myhandler();
下面是我们的Myhandler的实例代码。
1 package com.imooc.handler; 2 3 import org.xml.sax.Attributes; 4 import org.xml.sax.SAXException; 5 import org.xml.sax.helpers.DefaultHandler; 6 7 /* 8 * 解析xml处理器 9 * 10 * */ 11 public class Myhandler extends DefaultHandler{ 12 String value = null; 13 /** 14 * 用来标识解析开始 15 */ 16 @Override 17 public void startDocument() throws SAXException { 18 // TODO Auto-generated method stub 19 super.startDocument(); 20 System.out.println("SAX解析开始"); 21 } 22 23 /** 24 * 用来标识解析结束 25 */ 26 @Override 27 public void endDocument() throws SAXException { 28 // TODO Auto-generated method stub 29 super.endDocument(); 30 System.out.println("SAX解析结束"); 31 } 32 33 /** 34 * 解析xml元素 35 */ 36 @Override 37 public void startElement(String uri, String localName, String qName, 38 Attributes attributes) throws SAXException { 39 // TODO Auto-generated method stub 40 super.startElement(uri, localName, qName, attributes); 41 if (qName.equals("book")) { 42 int num = attributes.getLength(); 43 for(int i = 0; i < num; i++){ 44 System.out.print("book元素的第" + (i + 1) + "个属性名是:" 45 + attributes.getQName(i)); 46 System.out.println("---属性值是:" + attributes.getValue(i)); 47 48 } 49 }else if (!qName.equals("name") && !qName.equals("bookstore")) { 50 51 System.out.print("节点名是:" + qName + "---"); 52 } 53 } 54 55 @Override 56 public void endElement(String uri, String localName, String qName) 57 throws SAXException { 58 // TODO Auto-generated method stub 59 super.endElement(uri, localName, qName); 60 61 } 62 63 @Override 64 public void characters(char[] ch, int start, int length) 65 throws SAXException { 66 // TODO Auto-generated method stub 67 super.characters(ch, start, length); 68 value = new String(ch, start, length); 69 if (!value.trim().equals("")) { 70 System.out.println("节点值是:" + value); 71 } 72 } 73 74 75 76 }
(4)、测试主程序入口
1 public static void main(String[] args) { 2 3 SAXParserFactory factory = SAXParserFactory.newInstance(); 4 5 try { 6 SAXParser parser = factory.newSAXParser(); 7 8 Myhandler handler = new Myhandler(); 9 parser.parse("books.xml", handler); 10 11 } catch (ParserConfigurationException e) { 12 // TODO Auto-generated catch block 13 e.printStackTrace(); 14 } catch (SAXException e) { 15 // TODO Auto-generated catch block 16 e.printStackTrace(); 17 } catch (IOException e) { 18 // TODO Auto-generated catch block 19 e.printStackTrace(); 20 } 21 }
books.xml文件,
1 <?xml version="1.0" encoding="UTF-8"?> 2 <bookstore> 3 <book id="1"> 4 <name>老人与海</name> 5 <author>海明威</author> 6 <year>1955</year> 7 <price>45</price> 8 </book> 9 <book id="2"> 10 <name>书剑恩仇录</name> 11 <year>1959</year> 12 <price>24</price> 13 <language>chinese</language> 14 </book> 15 </bookstore>
输出的结果为:
SAX解析开始 book元素的第1个属性名是:id---属性值是:1 节点值是:老人与海 节点名是:author---节点值是:海明威 节点名是:year---节点值是:1955 节点名是:price---节点值是:45 book元素的第1个属性名是:id---属性值是:2 节点值是:书剑恩仇录 节点名是:year---节点值是:1959 节点名是:price---节点值是:24 节点名是:language---节点值是:chinese SAX解析结束
这样我们就完成了最基本的SAX解析xml文档。
总结:
优点:对内存要求比较低,对文档中的部分数据来进行解析开发速度快,而且扩展能力强。
缺点:用SAX方式进行XML解析时,需要顺序执行,所以很难访问到同一文档中的不同数据.此外,在基于该方式的解析编码过程也相对复杂