Android数据解析-----解析xml数据

我们在开发Android应用的过程中难免会与网络请求接触,网路请求获得的数据一般都是有一定的格式或者约定的形式来返回,这时候我们就需要对返回的数据进行解析,然后从中提取出我们需要呈现在界面上的数据,一般我们遇到的最常见的两种便于网络传输的数据类型便是xml和json,下面就详细介绍一下有关他们的解析方式。

一、xml数据解析

首先我们先定义一段xml数据。

<apps>
    <app>
        <id>1</id>
        <name>Google</name>
        <version>1.0</version>
    </app>
    <app>
        <id>2</id>
        <name>Android</name>
        <version>2.0</version>
    </app>
    <app>
        <id>3</id>
        <name>Play</name>
        <version>3.0</version>
    </app>
</apps>

方式一、Pull解析xml数据

1、获得XmlPullParserFactory实例

XmlPullParserFactory factory = XmlPullParserFactory.newInstance();

2、 获得XmlPullParser实例

XmlPullParser xmlPullParser = factory.newPullParser();

3、设置需要解析的数据

xmlPullParser.setInput(new StringReader(xmlData));

4、获得当前的解析事件

int eventType = xmlPullParser.getEventType();

5、解析结点,知道xml数据解析完成

下面是一个简单的小例子来解析最上面给出的xml数据

/**
 * 使用Pull解析xml数据
 */
private void parseXmlDataWithPull(String xmlData) {
    try {
        //获得XmlPullParserFactory实例
        XmlPullParserFactory factory = XmlPullParserFactory.newInstance();
        //获得XmlPullParser实例
        XmlPullParser xmlPullParser = factory.newPullParser();
        //将需要解析的数据设置进去
        xmlPullParser.setInput(new StringReader(xmlData));
        //获得当前的解析事件
        int eventType = xmlPullParser.getEventType();
        String id = "";
        String name = "";
        String version = "";
        //判断解析工作是否完成
        while (eventType != XmlPullParser.END_DOCUMENT){
            String nodeName = xmlPullParser.getName();
            switch (eventType){
                //开始解析某个结点
                case XmlPullParser.START_TAG:
                    if ("id".equals(nodeName)){
                        id = xmlPullParser.nextText();
                    }else if ("name".equals(nodeName)){
                        name = xmlPullParser.nextText();
                    }else if ("version".equals(nodeName)){
                        version = xmlPullParser.nextText();
                    }
                    break;
                //完成解析某个结点
                case XmlPullParser.END_TAG:
                    if ("app".equals(nodeName)){
                        Log.d("xiao", "id " + id);
                        Log.d("xiao", "name " + name);
                        Log.d("xiao", "version " + version);
                    }
                    break;
                default:
                    break;
            }
            //获取下一个解析事件
            eventType = xmlPullParser.next();
        }

    } catch (XmlPullParserException e) {
        e.printStackTrace();
    } catch (IOException e) {
        e.printStackTrace();
    }
}

方式二、SAX解析xml数据

SAX解析虽然比Pull解析复杂一点,但在语义理解方面更加清楚,下面是它的具体用法。

1、创建一个类继承自DefaultHandler,并重写其中的5个方法。

public class MyHandler extends DefaultHandler {
   private String nodeName;
   private StringBuilder id;
   private StringBuilder name;
   private StringBuilder version;



   //在开始进行xml解析的时候调用
   @Override
   public void startDocument() throws SAXException {
       id = new StringBuilder();
       name = new StringBuilder();
       version = new StringBuilder();
   }

   //开始解析某个结点的时候调用
   @Override
   public void startElement(String uri, String localName, String qName, Attributes attributes) throws SAXException {
       //记录当前的结点名
       nodeName = localName;
   }

   //在获取结点中内容的时候调用
   @Override
   public void characters(char[] ch, int start, int length) throws SAXException {
       //根据当前的结点名判断将内容添加到哪一个StringBuilder对象中
       if ("id".equals(nodeName)){
           id.append(ch, start, length);
       }else if ("name".equals(nodeName)){
           name.append(ch, start, length);
       }else if ("version".equals(nodeName)){
           version.append(ch, start, length);
       }
   }

   //某个结点解析完成的时候调用
   @Override
   public void endElement(String uri, String localName, String qName) throws SAXException {
       if ("app".equals(localName)){
           //去掉可能包含的回车符和换行符
           Log.d("GGGG", "id " + id.toString().trim());
           Log.d("GGGG", "name " + name.toString().trim());
           Log.d("GGGG", "version " + version.toString().trim());
           //清空StringBuilder
           id.setLength(0);
           name.setLength(0);
           version.setLength(0);
       }
   }

   //完成整个xml解析的时候调用
   @Override
   public void endDocument() throws SAXException {
       super.endDocument();
   }
}

2、获得SAXParserFactory的实例

SAXParserFactory factory = SAXParserFactory.newInstance();

3、获得XMLReader的实例

XMLReader xmlReader = factory.newSAXParser().getXMLReader();

4、获得我们自己定义的处理类的实例

MyHandler handler = new MyHandler();

5、将MyHandler类的实例设置到XMLReader中

xmlReader.setContentHandler(handler);

6、开始解析

xmlReader.parse(new InputSource(new StringReader(xmlData)));

下面给出完整的代码,解析最上面给出的xml文件

/**
 * 用Sax解析xml数据
 * @param xmlData
 */
private void parseXmlDataWithSax(String xmlData){
    //获得SAXParserFactory的实例
    SAXParserFactory factory = SAXParserFactory.newInstance();
    try {
        //获得XMLReader的实例
        XMLReader xmlReader = factory.newSAXParser().getXMLReader();
        //获得我们自己定义的处理类的实例
        MyHandler handler = new MyHandler();
        //将MyHandler类的实例设置到XMLReader中
        xmlReader.setContentHandler(handler);
        //开始解析
        xmlReader.parse(new InputSource(new StringReader(xmlData)));
    } catch (SAXException e) {
        e.printStackTrace();
    } catch (ParserConfigurationException e) {
        e.printStackTrace();
    } catch (IOException e) {
        e.printStackTrace();
    }
}

方式三、Dom解析xml数据

Dom解析也是xml常用的一种解析方式,但由于它在解析时是将整个文档树全部加载到内存中,所以它一般只用来解析文档规模较小的场景,下面是一段简单的代码来解析文档最开头给出的那段xml文档。

/**
 * 使用Dom解析xml
 *
 * @param xmlData
 */
private void parseXmlWithDom(String xmlData) {
    //得到DOM解析器的工厂实例
    DocumentBuilderFactory dbFactory = DocumentBuilderFactory.newInstance();
    //从DOM工厂中获得DOM解析器
    DocumentBuilder dbBuilder = null;
    try {
        dbBuilder = dbFactory.newDocumentBuilder();
        //把要解析的xml文档读入DOM解析器
        Document doc = dbBuilder.parse(new InputSource(new StringReader(xmlData)));
        //得到文档名称为app的元素的节点列表
        NodeList nList = doc.getElementsByTagName("app");
        //遍历该集合,显示集合中的元素及其子元素的名字
        for(int i = 0; i< nList.getLength() ; i ++){
            //Node转型WieElement
            Element node = (Element)nList.item(i);
            Log.d("MMMM", "id: "+ node.getElementsByTagName("id").item(0).getFirstChild().getNodeValue());
            Log.d("MMMM", "name: "+ node.getElementsByTagName("name").item(0).getFirstChild().getNodeValue());
            Log.d("MMMM", "version: "+ node.getElementsByTagName("version").item(0).getFirstChild().getNodeValue());

        }
    } catch (ParserConfigurationException e) {
        e.printStackTrace();
    } catch (SAXException e) {
        e.printStackTrace();
    } catch (IOException e) {
        e.printStackTrace();
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值