Java用SAX解析XML

来源:互联网 发布:淘宝产品视频 编辑:程序博客网 时间:2024/05/14 03:03

要解析的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     @Override100     public void endDocument() throws SAXException {101         // TODO Auto-generated method stub102         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 args18      */19     public static void main(String[] args) {20         // TODO Auto-generated method stub21         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()--name10 --characters()--11 --startElement()--sex12 --characters()--13 -----sex 男14 --endElement()--sex15 --characters()--16 --startElement()--age17 --characters()--18 -----age 2019 --endElement()--age20 --characters()--21 --endElement()--stu22 --characters()--23 --startElement()--stu24 --characters()--25 --startElement()--name26 --characters()--27 -----name namy28 --endElement()--name29 --characters()--30 --startElement()--sex31 --characters()--32 -----sex 女33 --endElement()--sex34 --characters()--35 --startElement()--age36 --characters()--37 -----age 1838 --endElement()--age39 --characters()--40 --endElement()--stu41 --characters()--42 --startElement()--stu43 --characters()--44 --startElement()--name45 --characters()--46 -----name lufy47 --endElement()--name48 --characters()--49 --startElement()--sex50 --characters()--51 -----sex 男52 --endElement()--sex53 --characters()--54 --startElement()--age55 --characters()--56 -----age 1857 --endElement()--age58 --characters()--59 --endElement()--stu60 --characters()--61 --endElement()--class62 --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()方法只会在文档解析结束的时候被调用,每次解析只会调用一次
0 0
原创粉丝点击