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

[原文]   http://blog.csdn.net/neu_yousei/article/details/22647937


本文讲解三点: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

<?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>

客户端程序运行结果:

--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

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

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

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

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

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
  }

}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值