zoukankan      html  css  js  c++  java
  • 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}]
    

      

     

     

  • 相关阅读:
    安卓中像素px和dp的转换
    Android 使用Vector XML文件创建矢量图片资源,editText监听
    动态设置RecyclerView的高度
    EditText一些用法
    各种加密算法比较
    多线程--Task,等待用户输入AutoResetEvent
    AutoCAD二次开发——AutoCAD.NET API开发环境搭建
    Office(Excel、Word)二次开发——VSTO
    个人信息管理PIM——密码管理工具软件
    【矩阵计算】矩阵乘法其一:基础符号和算法
  • 原文地址:https://www.cnblogs.com/caroline4lc/p/4972636.html
Copyright © 2011-2022 走看看