Blog / 阅读

sax中DefaultHander解析xml过程和先后顺序

by admin on 2014-03-31 12:49:59 in ,



本文讲解三点:1. sax中DefaultHandler解析XML总体过程  2. sax中DefaultHandler解析XML非根node的先后顺序 3. sax中DefaultHandler解析XML根node先后顺序 (三点 均通过实际程序测试出来,程序见下文)


一:sax中DefaultHandler解析XML总体过程
        startDocument--->具体读到某个node(非根node和根node)的解析过程 --->endDocument 。

二:DefaultHandler 解析XML 的非根node是按顺序的四步(不管当前node是ElementNode[可有属性]还是TextNode)(非根node本测试程序如 person,name,age):

        第一步:startElement.   (eg:startElement localName :  qName : age)
        第二步 :  characters       (eg:characters in age = 25) 
        第三步 :  endElement     (eg: endElement in )
        第四步 :  characters       (eg: characters in null =  !)

三:DefaultHandler 解析XML 的根node是按顺序的三步(本测试程序中根node为 persons):

        第一步:startElement.   (eg:startElement localName :  qName : persons)
        第二步 :  characters       (eg:characters in persons =             !) 
        第三步 :  endElement     (eg:endElement in )        
---------------------------------------------------------------------------------------------------------------------------------------

使用org.sax.helper.DefaultHandler 解析XML ,一般会调用以下六个方法,需要你重写。

1. 开始解析xml文档 startDocument
2. 读到某个节点 startElement-->characters-->endElement-->characters  (endElement后会再调用一次characters方法)    
3. 解析xml文档结束 endDocument  
--------------------------------------------------------------------------------------------------------------------------------------
org.sax.helper.DefaultHandler 解析XML 的算法思路(自己理解的)

对每一个非根节点node都要进行两项检查:1.检查是不是ElementNode(用startElement方法) ; 2.是不是TextNode(用characters方法),遇到当前节点结尾时,调用endElement和characters方法。最关键的一句话:DefaultHandler会自动解析到下个节点,通过调用startElement方法。并把最新解析到的节点名称放在startElement(Strng url , Sting localName , String qName , Attributes attributes) 的qName中。
---------------------------------------------------------------------------------------------------------------------------------------

测试程序:

客户端eclipse读取服务器端myeclpse的myhttp工程根目录下的persons.xml文件


persons.xml
[html] view plaincopy
<?xml version = "1.0" encoding = "UTF-8">  
<persons>  
    <person id="23">  
        <name>黄老师</name>  
        <age>26</age>  
    </person>  
    <person id="25">  
        <name>杨老师</name>  
        <age>28</age>  
    </person>  
</persons>  
客户端程序运行结果:

[html] view plaincopy
--startDocument--  
startElement localName: qName:persons  
characters in persons=  
    !  
startElement localName: qName:person  
characters in person=  
        !  
startElement localName: qName:name  
characters in name=黄老师!  
endElement in   
characters in null=  
        !  
startElement localName: qName:age  
characters in age=26!  
endElement in   
characters in null=  
    !  
endElement in   
characters in null=  
    !  
startElement localName: qName:person  
characters in person=  
        !  
startElement localName: qName:name  
characters in name=杨老师!  
endElement in   
characters in null=  
        !  
startElement localName: qName:age  
characters in age=28!  
endElement in   
characters in null=  
    !  
endElement in   
characters in null=  
!  
endElement in   
--endDocument--  
{name=黄老师, id=23, age=26}  
{name=杨老师, id=25, age=28}  
1.分析对每一个非根节点都会按顺序触发4个方法,如<age>和<person>;
对于<age>这个节点很直观可以看到,对于<person>其实也是如此,以person为黄老师为例: 刚开始解析到person节点(即 解析到<person>时),触发startElement和characters;当遍历完 name 和 age节点 到达</person> 时,触发了 endElement 和 characters方法

2.而对于根节点<persons>只触发前三个方法,而不触发最后一个characters方法。
因为xml文档必须包含一个根节点,且只能包含一个根节点,即本xml的根节点为<persons>具有唯一性,所以当解析遇到</persons>时会知道整个xml文档已经解析完毕,所以不会触发characters方法。而是在endElement后直接触发endDocument方法。

客户端eclipse程序目录(左边), 服务器端myeclipse程序目录(右边)

MyHandler2.java


[java] view plaincopy
package com.sax.handler;  
  
import java.util.ArrayList;  
import java.util.HashMap;  
import java.util.List;  
  
import org.xml.sax.Attributes;  
import org.xml.sax.SAXException;  
import org.xml.sax.helpers.DefaultHandler;  
  
public class MyHandler2 extends DefaultHandler {  
  
    private List<HashMap<String, String>> list = null;  
    private HashMap<String, String> map = null;  
  
    private String currentTag = null;  
    private String nodeName = null;  
  
    public MyHandler2(String nodeName) {  
        // TODO Auto-generated constructor stub  
        this.nodeName = nodeName;  
    }  
  
    public List<HashMap<String, String>> getList() {  
        return list;  
    }  
  
    @Override  
    public void startDocument() throws SAXException {  
        System.out.println("--startDocument--");  
        list = new ArrayList<HashMap<String, String>>();  
    }  
  
    @Override  
    public void startElement(String url, String localName, String qName,  
            Attributes attributes) throws SAXException {  
  
        System.out.println("startElement localName: " + localName + "qName:"  
                + qName);  
        currentTag = qName;  
        if (nodeName.equals(qName)) { // nodeName 是 person ,由构造函数传入。  
            map = new HashMap<String, String>();  
            map.put("id", attributes.getValue("id"));  
        }  
    }  
  
    @Override  
    public void characters(char[] arg0, int arg1, int arg2) throws SAXException {  
  
        System.out.println("characters in " + currentTag + "="  
                + new String(arg0, arg1, arg2) + "!");  
  
        if ("name".equals(currentTag)) {  
            map.put("name", new String(arg0, arg1, arg2));  
        }  
        if ("age".equals(currentTag)) {  
            map.put("age", new String(arg0, arg1, arg2));  
        }  
    }  
  
    @Override  
    public void endElement(String url, String localName, String qName)  
            throws SAXException {  
        System.out.println("endElement in " + localName);  
        if ("person".equals(qName)) {  
  
            list.add(map);  
        }  
        currentTag = null;  
    }  
  
    @Override  
    public void endDocument() throws SAXException {  
        System.out.println("--endDocument--");  
    }  
  
}  


SaxService.java


[java] view plaincopy
package com.sax.service;  
  
import java.io.IOException;  
import java.io.InputStream;  
import java.util.HashMap;  
import java.util.List;  
  
import javax.xml.parsers.ParserConfigurationException;  
import javax.xml.parsers.SAXParser;  
import javax.xml.parsers.SAXParserFactory;  
  
import org.xml.sax.SAXException;  
  
import com.sax.handler.MyHandler;  
import com.sax.handler.MyHandler2;  
  
public class SaxService {  
  
    public SaxService() {  
        // TODO Auto-generated constructor stub  
    }  
  
    public static List<HashMap<String, String>> readXML(  
            InputStream inputStream, String nodeName) {  
  
        try {  
            // 创建一个解析XML的工厂对象  
            SAXParserFactory spf = SAXParserFactory.newInstance();  
            SAXParser parser = spf.newSAXParser();  
            // MyHandler handler = new MyHandler(nodeName);  
            MyHandler2 handler = new MyHandler2(nodeName);  
  
            parser.parse(inputStream, handler);  
            inputStream.close();  
            // return handler.getList();  
            return handler.getList();  
  
        } catch (ParserConfigurationException e) {  
            // TODO Auto-generated catch block  
            e.printStackTrace();  
        } catch (SAXException e) {  
            // TODO Auto-generated catch block  
            e.printStackTrace();  
        } catch (IOException e) {  
            // TODO Auto-generated catch block  
            e.printStackTrace();  
        }  
  
        return null;  
  
    }  
}  
HttpUtils.java


[java] view plaincopy
package com.sax.http;  
  
import java.io.IOException;  
import java.io.InputStream;  
import java.net.HttpURLConnection;  
import java.net.MalformedURLException;  
import java.net.URL;  
  
public class HttpUtils {  
  
    public HttpUtils() {  
        // TODO Auto-generated constructor stub  
    }  
  
    public static InputStream getXML(String path) {  
  
        InputStream inputStream = null;  
  
        try {  
            URL url = new URL(path);  
  
            if (url != null) {  
                HttpURLConnection httpURLConnection = (HttpURLConnection) url  
                        .openConnection();  
                httpURLConnection.setConnectTimeout(3000);  
                httpURLConnection.setDoInput(true); // 从服务器获取数据  
                httpURLConnection.setRequestMethod("GET");  
  
                int responseCode = httpURLConnection.getResponseCode();  
  
                if (responseCode == 200) {  
                    inputStream = httpURLConnection.getInputStream();  
                }  
            }  
  
        } catch (MalformedURLException e) {  
            // TODO Auto-generated catch block  
            e.printStackTrace();  
        } catch (IOException e) {  
            // TODO Auto-generated catch block  
            e.printStackTrace();  
        }  
  
        return inputStream;  
  
    }  
  
}  
Test.java


[java] view plaincopy
package com.sax.test;  
  
import java.io.InputStream;  
import java.util.ArrayList;  
import java.util.HashMap;  
import java.util.Iterator;  
import java.util.List;  
import java.util.Map;  
  
import com.sax.handler.MyHandler;  
import com.sax.http.HttpUtils;  
import com.sax.service.SaxService;  
  
public class Test {  
  
    public Test() {  
        // TODO Auto-generated constructor stub  
    }  
  
    /** 
     * @param args 
     */  
    public static void main(String[] args) {  
        // TODO Auto-generated method stub  
        List<HashMap<String, String>> list = new ArrayList<HashMap<String,String>>();         
          
        InputStream inputStream = HttpUtils.getXML("http://192.168.0.102:8080/myhttp/persons.xml");   
      
        list = SaxService.readXML(inputStream, "person");  
          
        for (HashMap<String, String> hashMap : list) {  
            System.out.println(hashMap.toString());  
        }  
          
          
          
  
    }  
  
}  


服务器端 LoginAction.java


[java] view plaincopy
package com.login.manager;  
  
import java.io.IOException;  
import java.io.PrintWriter;  
  
import javax.servlet.ServletException;  
import javax.servlet.http.HttpServlet;  
import javax.servlet.http.HttpServletRequest;  
import javax.servlet.http.HttpServletResponse;  
  
public class LoginAction extends HttpServlet {  
  
    /** 
     * Constructor of the object. 
     */  
    public LoginAction() {  
        super();  
    }  
  
    /** 
     * Destruction of the servlet. <br> 
     */  
    public void destroy() {  
        super.destroy(); // Just puts "destroy" string in log  
        // Put your code here  
    }  
  
    /** 
     * The doGet method of the servlet. <br> 
     *  
     * This method is called when a form has its tag value method equals to get. 
     *  
     * @param request 
     *            the request send by the client to the server 
     * @param response 
     *            the response send by the server to the client 
     * @throws ServletException 
     *             if an error occurred 
     * @throws IOException 
     *             if an error occurred 
     */  
    public void doGet(HttpServletRequest request, HttpServletResponse response)  
            throws ServletException, IOException {  
  
        this.doPost(request, response);  
    }  
  
    /** 
     * The doPost method of the servlet. <br> 
     *  
     * This method is called when a form has its tag value method equals to 
     * post. 
     *  
     * @param request 
     *            the request send by the client to the server 
     * @param response 
     *            the response send by the server to the client 
     * @throws ServletException 
     *             if an error occurred 
     * @throws IOException 
     *             if an error occurred 
     */  
    public void doPost(HttpServletRequest request, HttpServletResponse response)  
            throws ServletException, IOException {  
  
        response.setContentType("text/html;charset=utf-8");  
        request.setCharacterEncoding("utf-8");  
        response.setCharacterEncoding("utf-8");  
        //客户端 HttpUtils并没有写request方法是post ,但服务器端可自动识别  
        String method = request.getMethod();  
        System.out.println("request method :"+method);  
          
          
        PrintWriter out = response.getWriter();  
        String username = request.getParameter("username");  
        System.out.println("-username->>"+username);  
          
        String password = request.getParameter("password");  
        System.out.println("-password->>"+password);  
  
        if (username.equals("admin") && password.equals("123")) {  
            // 表示服务器段返回的结果  
            out.print("login is success !");  
  
        } else {  
            out.print("login is fail !");  
        }  
  
        out.flush();  
        out.close();  
    }  
  
    /** 
     * Initialization of the servlet. <br> 
     *  
     * @throws ServletException 
     *             if an error occurs 
     */  
    public void init() throws ServletException {  
        // Put your code here  
    }  
  
}  



写评论

相关文章

上一篇:eclipse中怎么没有智能提示了啊?(按下‘.’时显示)

下一篇:DES加密算法详解- -

评论

写评论

* 必填.

分享

栏目

赞助商


热门文章

Tag 云