• 12.4.2 SAX分析


        为了使用Android上内置的SAX分析器,首先需要创建扩展DefaultHandler的新类。这个类将包含一些方法,可以使用户在启动、停止一个XML元素以及在读取内容时获得通知。下面是一个基本的版本,其仅仅输出日志。

     1     private class UserXMLHandler extends DefaultHandler{
     2         @Override
     3         public void startDocument() throws SAXException {
     4             super.startDocument();
     5             Log.v("SimpleXMLParser", "startDocument");
     6         }
     7         @Override
     8         public void endDocument() throws SAXException {
     9             super.endDocument();
    10             Log.v("SimpleXMLParser", "endDocument");
    11         }
    12         @Override
    13         public void startElement(String uri, String localName, String qName,
    14                 Attributes attributes) throws SAXException {
    15             super.startElement(uri, localName, qName, attributes);
    16             Log.v("SimpleXMLParser", "startElement"+localName);
    17         }
    18         @Override
    19         public void endElement(String uri, String localName, String qName)
    20                 throws SAXException {
    21             super.endElement(uri, localName, qName);
    22             Log.v("SimpleXMLParser", "endElement"+localName);
    23         }
    24         @Override
    25         public void characters(char[] ch, int start, int length)
    26                 throws SAXException {
    27             super.characters(ch, start, length);
    28             String stringChars=new String(ch,start,length);
    29             Log.v("SimpleXMLParser",stringChars);
    30         }
    31     }

        一旦获得该类,就可以创建一个SAXParserFactory实例,然后创建一个SAXParser实例。

    1         SAXParserFactory aSAXParserFactory=SAXParserFactory.newInstance();
    2         SAXParser aSAXParser=aSAXParserFactory.newSAXParser();

        通过SAXParser对象可以得到一个XMLReader,用来确定在分析时会发生什么,并执行实际的分析。

    1             XMLReader anXMLReader=aSAXParser.getXMLReader();

        然后实例化XMLHandler,并将它传递给XMLReader上的setContentHandler方法。

    1             XMLHandler anUserXMLHandler=new XMLHandler();
    2             anXMLReader.setContentHandler(anUserXMLHandler);

        最后调用XMLReader上的parse方法。在当前的情况下,假设有一个称为xmlInputStream的InputStream,其中包含了将要分析的XML。

    1             anXMLReader.parse(new InputSource(xmlInputStream));

        下面查看一个完整的示例,其显示了如何分析前述的“用户”XML。

     1 package com.nthm.androidtestActivity;
     2 
     3 import java.io.ByteArrayInputStream;
     4 import java.io.IOException;
     5 import javax.xml.parsers.ParserConfigurationException;
     6 import javax.xml.parsers.SAXParser;
     7 import javax.xml.parsers.SAXParserFactory;
     8 import org.xml.sax.Attributes;
     9 import org.xml.sax.InputSource;
    10 import org.xml.sax.SAXException;
    11 import org.xml.sax.XMLReader;
    12 import org.xml.sax.helpers.DefaultHandler;
    13 import android.app.Activity;
    14 import android.os.Bundle;
    15 import android.util.Log;
    16 
    17 public class SimpleXMLParser extends Activity {

        需要将XML转换成名为XMLUser的类(在本代码的末尾定义该类)的实例,它将是在XML中定义的数据的java表示。

    1     private XMLUser aUser;
    2     @Override
    3     protected void onCreate(Bundle savedInstanceState) {
    4         super.onCreate(savedInstanceState);
    5         setContentView(R.layout.main);

        此示例将要分析的XML包含在一个称为xml的字符串中。

    1         String xml="<?xml version="1.0"?>
    "
    2                     +"<user>
    "
    3                     +"<user-id>15</user-id>
    "
    4                     +"<username>vanevery</username>
    "
    5                     +"<firstname>Shawn</firstname>
    "
    6                     +"<lastname>Van Every</lastname>
    "
    7                     +"</user>
    ";

        下面将依次执行之前所描述的步骤,并创建SAXParserFactory、SAXParser和XMLReader。

    1         SAXParserFactory aSAXParserFactory=SAXParserFactory.newInstance();
    2         try {
    3             SAXParser aSAXParser=aSAXParserFactory.newSAXParser();
    4             XMLReader anXMLReader=aSAXParser.getXMLReader();

        然后,将使用下面定义的UserXMLHandler实例作为处理程序,用来确定当分析时会发生的事情。

    1             UserXMLHandler aUserXMLHandler=new UserXMLHandler();
    2             anXMLReader.setContentHandler(aUserXMLHandler);

        最后将执行实际的分析。必须做一些额外的工作,将位于xml字符串中的XML转换成一个InputStream和一个能够通过XMLReader使用的InputSource。

    1             anXMLReader.parse(new InputSource(new ByteArrayInputStream(xml.getBytes())));
    2         } catch (ParserConfigurationException e) {
    3             e.printStackTrace();
    4         } catch (SAXException e) {
    5             e.printStackTrace();
    6         }catch (IOException e) {
    7             e.printStackTrace();
    8         }
    9     }

        此示例的主要内容是UserXMLHandler。它扩展了DefaultHandler,而且将随着对XML的分析获得它的数据。

    1     private class UserXMLHandler extends DefaultHandler{

        我们将使用以下常量并结合state变量来跟踪已经读入了哪些元素。

    1         static final int NONE=0;
    2         static final int ID=1;
    3         static final int FIRSTNAME=2;
    4         static final int LASENAME=3;
    5         int state=NONE;

        我们将使用以下常量来匹配在XML中可能出现的元素的名称。

    1         static final String ID_ELEMENT="user-id";
    2         static final String FIRSTNAME_ELEMENT="firstname";
    3         static final String LASTNAME_ELEMENT="lastname";

       当分析器确定一个XML文档已经开始时,将调用startDocument方法,在此方法中实例化XMLUser对象,以保存在XML中表示的数据。

    1         @Override
    2         public void startDocument() throws SAXException {
    3             super.startDocument();
    4             Log.v("SimpleXMLParser", "startDocument");
    5             aUser=new XMLUser();
    6         }

        当分析器确定XML文档已经完成时,将调用endDocument方法。此处将只输出XMLUser对象中的内容。

    1         @Override
    2         public void endDocument() throws SAXException {
    3             super.endDocument();
    4             Log.v("SimpleXMLParser", "endDocument");
    5             Log.v("SimpleXMLParser", "User info:"+aUser.user_id+" "+aUser.firstname+" "+aUser.lastname);
    6         }

        当确定了一个新元素开始时,将调用startElement方法。换言之,在XML中发现一个开始标记。将通过localName变量传入该元素的名称。在此方法中只会将该名称与前面定义的常量相比较,并使用它来更改state变量。

     1         @Override
     2         public void startElement(String uri, String localName, String qName,
     3                 Attributes attributes) throws SAXException {
     4             super.startElement(uri, localName, qName, attributes);
     5             Log.v("SimpleXMLParser", "startElement"+localName);
     6             if(localName.equalsIgnoreCase(ID_ELEMENT)){
     7                 state=ID;
     8             }else if(localName.equalsIgnoreCase(FIRSTNAME_ELEMENT)){
     9                 state=FIRSTNAME;
    10             }else if(localName.equalsIgnoreCase(LASTNAME_ELEMENT)){
    11                 state=LASENAME;
    12             }else{
    13                 state=NONE;
    14             }
    15         }

        当发现任何XML结束标记时,将调用endElement方法。

    1         @Override
    2         public void endElement(String uri, String localName, String qName)
    3                 throws SAXException {
    4             super.endElement(uri, localName, qName);
    5             Log.v("SimpleXMLParser", "endElement"+localName);
    6         }

       每当在开始标记和结束标记之间发现文本时,将调用characters方法。在当前实现中将接受数据,并根据state变量表示的再文档中所处的位置将它放入XMLUser对象。

     1         @Override
     2         public void characters(char[] ch, int start, int length)
     3                 throws SAXException {
     4             super.characters(ch, start, length);
     5             String stringChars=new String(ch,start,length);
     6             Log.v("SimpleXMLParser",stringChars);
     7             if(state==ID){
     8                 aUser.user_id+=stringChars.trim();
     9             }else if(state==FIRSTNAME){
    10                 aUser.firstname+=stringChars.trim();
    11             }else if(state==LASENAME){
    12                 aUser.lastname+=stringChars.trim();
    13             }
    14         }
    15     }

        下面是XMLUser类,它用来保存在XML中给定的数据。

     1     class XMLUser{
     2         private String user_id;
     3         private String firstname;
     4         private String lastname;
     5         public XMLUser(){
     6             user_id="";
     7             firstname="";
     8             lastname="";
     9         }
    10     }
    11 }

        在查看了这个简单的示例之后,可以将它作为在Android上实现任何XML分析的模板,包括处理所接收的用于响应Web服务请求的数据。

  • 相关阅读:
    BZOJ1257:[CQOI2007]余数之和——题解+证明
    BZOJ3781:小B的询问——题解
    BZOJ2038:[2009国家集训队]小Z的袜子——题解
    BZOJ3052 & UOJ58:[WC2013]糖果公园——题解
    BZOJ1086:[SCOI2005]王室联邦——题解
    BZOJ1878:[SDOI2009]HH的项链——题解
    BZOJ2453:维护队列——题解
    美团新零售招聘-高级测试开发(20k-50k/月)
    Shopee招聘-测试开发leader(30k-60k/月)
    蚂蚁金服招聘-无线测试开发(20k-36k/月)
  • 原文地址:https://www.cnblogs.com/ZSS-Android/p/3966849.html
Copyright © 2020-2023  润新知