java_XML_SAX
用SAX解析XML采用的是从上而下的基于事件驱动的解析方式,在解析过程中会视情况自动调用startDocument()、startElement()、characters()、endElement()、endDocument()等相关的方法。
由编译执行的结果来看:
- startDocument()方法只会在文档开始解析的时候被调用,每次解析只会调用一次。
- startElement()方法每次在开始解析一个元素,即遇到元素标签开始的时候都会调用。
- characters()方法也是在每次解析到元素标签携带的内容时都会调用,即使该元素标签的内容为空或换行。而且如果元素内嵌套元素,在父元素结束标签前, characters()方法会再次被调用,此处需要注意。
- endElement()方法每次在结束解析一个元素,即遇到元素标签结束的时候都会调用。
- endDocument() startDocument()方法只会在文档解析结束的时候被调用,每次解析只会调用一次。
要解析的XML文件:myClass.xml
<?xml version="1.0" encoding="utf-8"?> <class> <stu id="001"> <name>Allen</name> <sex>男</sex> <age>20</age> </stu> <stu id="002"> <name>namy</name> <sex>女</sex> <age>18</age> </stu> <stu id="003"> <name>lufy</name> <sex>男</sex> <age>18</age> </stu> </class>
用SAX解析XML的Handler类:Myhandler.java
/** * 用SAX解析XML的Handler */ package com.xml.util; import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; import org.xml.sax.Attributes; import org.xml.sax.SAXException; import org.xml.sax.helpers.DefaultHandler; public class Myhandler extends DefaultHandler { //存储正在解析的元素的数据 private Map<String,String> map=null; //存储所有解析的元素的数据 private List<Map<String,String>> list=null; //正在解析的元素的名字 String currentTag=null; //正在解析的元素的元素值 String currentValue=null; //开始解析的元素 String nodeName=null; public Myhandler(String nodeName) { // TODO Auto-generated constructor stub this.nodeName=nodeName; } public List<Map<String, String>> getList() { return list; } //开始解析文档,即开始解析XML根元素时调用该方法 @Override public void startDocument() throws SAXException { // TODO Auto-generated method stub System.out.println("--startDocument()--"); //初始化Map list=new ArrayList<Map<String,String>>(); } //开始解析每个元素时都会调用该方法 @Override public void startElement(String uri, String localName, String qName, Attributes attributes) throws SAXException { // TODO Auto-generated method stub //判断正在解析的元素是不是开始解析的元素 System.out.println("--startElement()--"+qName); if(qName.equals(nodeName)){ map=new HashMap<String, String>(); } //判断正在解析的元素是否有属性值,如果有则将其全部取出并保存到map对象中,如:<person id="00001"></person> if(attributes!=null&&map!=null){ for(int i=0;i<attributes.getLength();i++){ map.put(attributes.getQName(i), attributes.getValue(i)); } } currentTag=qName; //正在解析的元素 } //解析到每个元素的内容时会调用此方法 @Override public void characters(char[] ch, int start, int length) throws SAXException { // TODO Auto-generated method stub System.out.println("--characters()--"); if(currentTag!=null&&map!=null){ currentValue=new String(ch,start,length); //如果内容不为空和空格,也不是换行符则将该元素名和值和存入map中 if(currentValue!=null&&!currentValue.trim().equals("")&&!currentValue.trim().equals("\n")){ map.put(currentTag, currentValue); System.out.println("-----"+currentTag+" "+currentValue); } //当前的元素已解析过,将其置空用于下一个元素的解析 currentTag=null; currentValue=null; } } //每个元素结束的时候都会调用该方法 @Override public void endElement(String uri, String localName, String qName) throws SAXException { // TODO Auto-generated method stub System.out.println("--endElement()--"+qName); //判断是否为一个节点结束的元素标签 if(qName.equals(nodeName)){ list.add(map); map=null; } } //结束解析文档,即解析根元素结束标签时调用该方法 @Override public void endDocument() throws SAXException { // TODO Auto-generated method stub System.out.println("--endDocument()--"); super.endDocument(); } }
用于解析XML的业务类:SaxService.java
/** * 封装解析业务类 */ package com.xml.service; import java.io.InputStream; import java.util.List; import java.util.Map; import javax.xml.parsers.SAXParser; import javax.xml.parsers.SAXParserFactory; import com.xml.util.Myhandler; public class SaxService { public static List<Map<String,String>> ReadXML(String uri,String NodeName){ try { //创建一个解析XML的工厂对象 SAXParserFactory parserFactory=SAXParserFactory.newInstance(); //创建一个解析XML的对象 SAXParser parser=parserFactory.newSAXParser(); //创建一个解析助手类 Myhandler myhandler=new Myhandler("stu"); parser.parse(uri, myhandler); return myhandler.getList(); } catch (Exception e) { e.printStackTrace(); }finally{ } return null; } }
主程序入口:XmlSaxTest
/** * 程序入口 */ package com.xml.sax; import java.util.ArrayList; import java.util.HashMap; import java.util.Iterator; import java.util.List; import java.util.Map; import com.xml.service.SaxService; public class XmlSaxTest { /** * @param args */ public static void main(String[] args) { // TODO Auto-generated method stub ArrayList<Map<String, String>> list=(ArrayList<Map<String, String>>) SaxService.ReadXML("M:\\XML\\Demo\\myClass.xml","class"); /*for(int i=0;i<list.size();i++){ HashMap<String, String> temp=(HashMap<String, String>) list.get(i); Iterator<String> iterator=temp.keySet().iterator(); while(iterator.hasNext()){ String key=iterator.next().toString(); String value=temp.get(key); System.out.print(key+" "+value+"--"); } }*/ System.out.println(list.toString()); } }
执行结果:
--startDocument()-- --startElement()--class --characters()-- --startElement()--stu --characters()-- --startElement()--name --characters()-- -----name Allen --endElement()--name --characters()-- --startElement()--sex --characters()-- -----sex 男 --endElement()--sex --characters()-- --startElement()--age --characters()-- -----age 20 --endElement()--age --characters()-- --endElement()--stu --characters()-- --startElement()--stu --characters()-- --startElement()--name --characters()-- -----name namy --endElement()--name --characters()-- --startElement()--sex --characters()-- -----sex 女 --endElement()--sex --characters()-- --startElement()--age --characters()-- -----age 18 --endElement()--age --characters()-- --endElement()--stu --characters()-- --startElement()--stu --characters()-- --startElement()--name --characters()-- -----name lufy --endElement()--name --characters()-- --startElement()--sex --characters()-- -----sex 男 --endElement()--sex --characters()-- --startElement()--age --characters()-- -----age 18 --endElement()--age --characters()-- --endElement()--stu --characters()-- --endElement()--class --endDocument()-- [{id=001, sex=男, age=20, name=Allen}, {id=002, sex=女, age=18, name=namy}, {id=003, sex=男, age=18, name=lufy}]
posted on 2015-11-17 19:29 caroline_lc 阅读(184) 评论(0) 编辑 收藏 举报