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("
")){
                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}]

  

 

 

原文地址:https://www.cnblogs.com/caroline4lc/p/4972636.html