Java用SAX解析XML
要解析的XML文件:myClass.xml
1 <?xml version="1.0" encoding="utf-8"?> 2 <class> 3 <stu id="001"> 4 <name>Allen</name> 5 <sex>男</sex> 6 <age>20</age> 7 </stu> 8 <stu id="002"> 9 <name>namy</name> 10 <sex>女</sex> 11 <age>18</age> 12 </stu> 13 <stu id="003"> 14 <name>lufy</name> 15 <sex>男</sex> 16 <age>18</age> 17 </stu> 18 </class>
用SAX解析XML的Handler类:Myhandler.java
1 /** 2 * 用SAX解析XML的Handler 3 */ 4 package com.xml.util; 5 6 import java.util.ArrayList; 7 import java.util.HashMap; 8 import java.util.List; 9 import java.util.Map; 10 11 import org.xml.sax.Attributes; 12 import org.xml.sax.SAXException; 13 import org.xml.sax.helpers.DefaultHandler; 14 15 public class Myhandler extends DefaultHandler { 16 //存储正在解析的元素的数据 17 private Map<String,String> map=null; 18 //存储所有解析的元素的数据 19 private List<Map<String,String>> list=null; 20 //正在解析的元素的名字 21 String currentTag=null; 22 //正在解析的元素的元素值 23 String currentValue=null; 24 //开始解析的元素 25 String nodeName=null; 26 27 28 public Myhandler(String nodeName) { 29 // TODO Auto-generated constructor stub 30 this.nodeName=nodeName; 31 } 32 33 public List<Map<String, String>> getList() { 34 return list; 35 } 36 37 //开始解析文档,即开始解析XML根元素时调用该方法 38 @Override 39 public void startDocument() throws SAXException { 40 // TODO Auto-generated method stub 41 System.out.println("--startDocument()--"); 42 //初始化Map 43 list=new ArrayList<Map<String,String>>(); 44 } 45 46 //开始解析每个元素时都会调用该方法 47 @Override 48 public void startElement(String uri, String localName, String qName, 49 Attributes attributes) throws SAXException { 50 // TODO Auto-generated method stub 51 //判断正在解析的元素是不是开始解析的元素 52 System.out.println("--startElement()--"+qName); 53 if(qName.equals(nodeName)){ 54 map=new HashMap<String, String>(); 55 } 56 57 //判断正在解析的元素是否有属性值,如果有则将其全部取出并保存到map对象中,如:<person id="00001"></person> 58 if(attributes!=null&&map!=null){ 59 for(int i=0;i<attributes.getLength();i++){ 60 map.put(attributes.getQName(i), attributes.getValue(i)); 61 } 62 } 63 currentTag=qName; //正在解析的元素 64 } 65 66 //解析到每个元素的内容时会调用此方法 67 @Override 68 public void characters(char[] ch, int start, int length) 69 throws SAXException { 70 // TODO Auto-generated method stub 71 System.out.println("--characters()--"); 72 if(currentTag!=null&&map!=null){ 73 currentValue=new String(ch,start,length); 74 //如果内容不为空和空格,也不是换行符则将该元素名和值和存入map中 75 if(currentValue!=null&&!currentValue.trim().equals("")&&!currentValue.trim().equals("\n")){ 76 map.put(currentTag, currentValue); 77 System.out.println("-----"+currentTag+" "+currentValue); 78 } 79 //当前的元素已解析过,将其置空用于下一个元素的解析 80 currentTag=null; 81 currentValue=null; 82 } 83 } 84 85 //每个元素结束的时候都会调用该方法 86 @Override 87 public void endElement(String uri, String localName, String qName) 88 throws SAXException { 89 // TODO Auto-generated method stub 90 System.out.println("--endElement()--"+qName); 91 //判断是否为一个节点结束的元素标签 92 if(qName.equals(nodeName)){ 93 list.add(map); 94 map=null; 95 } 96 } 97 98 //结束解析文档,即解析根元素结束标签时调用该方法 99 @Override 100 public void endDocument() throws SAXException { 101 // TODO Auto-generated method stub 102 System.out.println("--endDocument()--"); 103 super.endDocument(); 104 } 105 }
用于解析XML的业务类:SaxService.java
1 /** 2 * 封装解析业务类 3 */ 4 package com.xml.service; 5 6 import java.io.InputStream; 7 import java.util.List; 8 import java.util.Map; 9 10 import javax.xml.parsers.SAXParser; 11 import javax.xml.parsers.SAXParserFactory; 12 13 import com.xml.util.Myhandler; 14 15 public class SaxService { 16 17 public static List<Map<String,String>> ReadXML(String uri,String NodeName){ 18 try { 19 //创建一个解析XML的工厂对象 20 SAXParserFactory parserFactory=SAXParserFactory.newInstance(); 21 //创建一个解析XML的对象 22 SAXParser parser=parserFactory.newSAXParser(); 23 //创建一个解析助手类 24 Myhandler myhandler=new Myhandler("stu"); 25 parser.parse(uri, myhandler); 26 return myhandler.getList(); 27 } catch (Exception e) { 28 e.printStackTrace(); 29 }finally{ 30 31 } 32 return null; 33 34 } 35 }
主程序入口:XmlSaxTest
1 /** 2 * 程序入口 3 */ 4 package com.xml.sax; 5 6 import java.util.ArrayList; 7 import java.util.HashMap; 8 import java.util.Iterator; 9 import java.util.List; 10 import java.util.Map; 11 12 import com.xml.service.SaxService; 13 14 public class XmlSaxTest { 15 16 /** 17 * @param args 18 */ 19 public static void main(String[] args) { 20 // TODO Auto-generated method stub 21 ArrayList<Map<String, String>> list=(ArrayList<Map<String, String>>) SaxService.ReadXML("M:\\XML\\Demo\\myClass.xml","class"); 22 /*for(int i=0;i<list.size();i++){ 23 HashMap<String, String> temp=(HashMap<String, String>) list.get(i); 24 Iterator<String> iterator=temp.keySet().iterator(); 25 while(iterator.hasNext()){ 26 String key=iterator.next().toString(); 27 String value=temp.get(key); 28 System.out.print(key+" "+value+"--"); 29 } 30 }*/ 31 System.out.println(list.toString()); 32 } 33 34 }
执行结果:
1 --startDocument()-- 2 --startElement()--class 3 --characters()-- 4 --startElement()--stu 5 --characters()-- 6 --startElement()--name 7 --characters()-- 8 -----name Allen 9 --endElement()--name 10 --characters()-- 11 --startElement()--sex 12 --characters()-- 13 -----sex 男 14 --endElement()--sex 15 --characters()-- 16 --startElement()--age 17 --characters()-- 18 -----age 20 19 --endElement()--age 20 --characters()-- 21 --endElement()--stu 22 --characters()-- 23 --startElement()--stu 24 --characters()-- 25 --startElement()--name 26 --characters()-- 27 -----name namy 28 --endElement()--name 29 --characters()-- 30 --startElement()--sex 31 --characters()-- 32 -----sex 女 33 --endElement()--sex 34 --characters()-- 35 --startElement()--age 36 --characters()-- 37 -----age 18 38 --endElement()--age 39 --characters()-- 40 --endElement()--stu 41 --characters()-- 42 --startElement()--stu 43 --characters()-- 44 --startElement()--name 45 --characters()-- 46 -----name lufy 47 --endElement()--name 48 --characters()-- 49 --startElement()--sex 50 --characters()-- 51 -----sex 男 52 --endElement()--sex 53 --characters()-- 54 --startElement()--age 55 --characters()-- 56 -----age 18 57 --endElement()--age 58 --characters()-- 59 --endElement()--stu 60 --characters()-- 61 --endElement()--class 62 --endDocument()-- 63 [{id=001, sex=男, age=20, name=Allen}, {id=002, sex=女, age=18, name=namy}, {id=003, sex=男, age=18, name=lufy}]
分析:用SAX解析XML采用的是从上而下的基于事件驱动的解析方式,在解析过程中会视情况自动调用startDocument()、startElement()、characters()、endElement()、endDocument()等相关的方法。
由编译执行的结果来看:
- startDocument()方法只会在文档开始解析的时候被调用,每次解析只会调用一次。
- startElement()方法每次在开始解析一个元素,即遇到元素标签开始的时候都会调用。
- characters()方法也是在每次解析到元素标签携带的内容时都会调用,即使该元素标签的内容为空或换行。而且如果元素内嵌套元素,在父元素结束标签前, characters()方法会再次被调用,此处需要注意。
- endElement()方法每次在结束解析一个元素,即遇到元素标签结束的时候都会调用。
- endDocument() startDocument()方法只会在文档解析结束的时候被调用,每次解析只会调用一次。