SAX方式解析XML
sax解析分为以下几步:
1 获取一个saxparserfactory
2 获取一个解析器
3 创建handler对象,这个myHandler是继承了DefaultHandler的一个类,这个实现类里写具体的解析逻辑
4 开始解析xml。
结构层次图:
具体如下面的代码:
mySAXparser:
package com.imooc.test; import java.io.IOException; import javax.xml.parsers.ParserConfigurationException; import javax.xml.parsers.SAXParser; import javax.xml.parsers.SAXParserFactory; import org.xml.sax.SAXException; public class mySAXparser { public static void main(String[] args) { //1 获取一个saxparserfactory SAXParserFactory factory = SAXParserFactory.newInstance(); try { //2 获取一个解析器 SAXParser parser = factory.newSAXParser(); /* * 3 创建handler对象,这个myHandler是继承了DefaultHandler的一个类 * 这个实现类里写具体的解析逻辑 */ myHandler handler = new myHandler(); //4 开始解析xml, parser.parse("books.xml",handler); } catch (ParserConfigurationException e) { // TODO Auto-generated catch block e.printStackTrace(); } catch (SAXException e) { // TODO Auto-generated catch block e.printStackTrace(); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } } }
myHandler:
package sax; import org.xml.sax.Attributes; import org.xml.sax.SAXException; import org.xml.sax.helpers.DefaultHandler; public class myHandler extends DefaultHandler { int i =0; int j = 0; String value = null; @Override public void startDocument() throws SAXException { // TODO Auto-generated method stub super.startDocument(); System.out.println("startDocument开始解析.............."); } @Override public void endDocument() throws SAXException { // TODO Auto-generated method stub super.endDocument(); System.out.println("endDocument结束解析............"); } @Override public void startElement(String uri, String localName, String qName, Attributes attributes) throws SAXException { // TODO Auto-generated method stub super.startElement(uri, localName, qName, attributes); /* * qName:The qualified name (with prefix), * or the empty string if qualified names are not available. * qName:实际上就是标签名的名字,如<sex>1</sex> 那么qName就代指的这个标签名,sex * */ if(qName.equals("book")){ i++; String value = attributes.getValue("size"); int len = attributes.getLength(); System.out.println("len:"+len); for(int k=0;k<len;k++){ int m = k+1; System.out.println("属性"+m+":"+attributes.getQName(k)); } System.out.println("book.size:"+value); System.out.println("第"+i+"处,解析到book元素的标签。。。"); } if(qName.equals("bookstore")){ j++; System.out.println("第"+j+"处,解析到bookstore元素的标签。。。"); } } @Override public void endElement(String uri, String localName, String qName) throws SAXException { // TODO Auto-generated method stub super.endElement(uri, localName, qName); System.out.println("第"+i+",endElement结束"); } @Override public void characters(char[] ch, int start, int length) throws SAXException { // TODO Auto-generated method stub super.characters(ch, start, length); //new String(ch, start, length)用来生成一个元素中标签之间的具体的文本 value = new String(ch, start, length);//加入正好解析到<name>冰与火之歌</name>时,那么value="冰与火之歌" System.out.println("================节点值是:" + value); if (!value.trim().equals("")) { System.out.println(i+"节点值是:" + value); } } }
books.xml:
<?xml version="1.0" encoding="UTF-8"?> <bookstore> <book id="1"> <name>冰与火之歌</name> <author>乔治马丁</author> <year>2014</year> <price>89</price> </book> <book id="2"> <name>安徒生童话</name> <year>2004</year> <price>77</price> <language>English</language> </book> </bookstore>
解析结果下:
startDocument开始解析..............
第1处,解析到bookstore元素的标签。。。
================节点值是:
len:2
属性1:id
属性2:size
book.size:23
第1处,解析到book元素的标签。。。
================节点值是:
================节点值是:冰与火之歌
1节点值是:冰与火之歌
第1,endElement结束
================节点值是:
================节点值是:乔治马丁
1节点值是:乔治马丁
第1,endElement结束
================节点值是:
================节点值是:2014
1节点值是:2014
第1,endElement结束
================节点值是:
================节点值是:89
1节点值是:89
第1,endElement结束
================节点值是:
第1,endElement结束
================节点值是:
len:1
属性1:id
book.size:null
第2处,解析到book元素的标签。。。
================节点值是:
================节点值是:安徒生童话
2节点值是:安徒生童话
第2,endElement结束
================节点值是:
================节点值是:2004
2节点值是:2004
第2,endElement结束
================节点值是:
================节点值是:77
2节点值是:77
第2,endElement结束
================节点值是:
================节点值是:English
2节点值是:English
第2,endElement结束
================节点值是:
第2,endElement结束
================节点值是:
第2,endElement结束
endDocument结束解析............
sax解析的myHandler这个类继承了DefaultHandler,具体的解析逻辑就是写在这个myHandler
中,覆盖的方法的执行顺序是:
1. startDocument()
2.
startElement(String uri, String localName, String qName,
Attributes attributes)
3. endElement(String uri, String localName, String qName)
4. characters(char[] ch, int start, int length)
...
n. endDocument()
其中的...省略号部分一直重复的执行2,3,4两个步骤,主要是根据xml的具体情形,遇到一个具体元素就会执行2,3,4三个步骤一次。如上面的
xml中的
<name>冰与火之歌</name>
<author>乔治马丁</author>
<year>2014</year>
<price>89</price>
,这样就会重复执行2,3,4步骤四次。