原文链接:http://www.orlion.ga/685/

解析XML常用的方式有两种,一种是PULL解析一种是SAX解析。

假设解析数据为:

<apps>
    <app>
        <id>1</id>
        <name>Google Maps</name>
        <version>1.0</version>
    </app>
    <app>
        <id>2</id>
        <name>Chrome</name>
        <version>2.1</version>
    </app>
    <app>
        <id>3</id>
        <name>Google Play</name>
        <version>2.3</version>
    </app>
</apps>

一、PULL解析

try {
    XmlPullParserFactory factory = XmlPullParserFactory.newInstance();
    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("MainActivity", "id is " + id);
                Log.d("MainActivity", "name is " + name);
                Log.d("MainActivity", "version is " + version);
            }
            break;
        }
        default:
            break;
        }
        eventType = xmlPullParser.next();
    }
} catch (Exception e) {
    e.printStackTrace();
}

首先要获取到一个XmlPullParserFactory 的实例,并借助这个实例得到 XmlPullParser 对象,然后调用XmlPullParser的 setInput()方法将服务器返回的 XML数据设置进去就可以开始解析了。解析的过程也是非常简单,通过 getEventType()可以得到当前的解析事件,然后在一个 while循环中不断地进行解析,如果当前的解析事件不等于 XmlPullParser.END_DOCUMENT,说明解

析工作还没完成,调用 next()方法后可以获取下一个解析事件。在 while循环中,我们通过 getName()方法得到当前结点的名字,如果发现结点名等于id、name或 version,就调用 nextText()方法来获取结点内具体的内容,每当解析完一个 app

结点后就将获取到的内容打印出来。

二、SAX解析方式

新建一个 ContentHandler类继承自 DefaultHandler,并重写父类的五个方法,如下所示:

public class ContentHandler extends DefaultHandler {
    private String nodeName;
    private StringBuilder id;
    private StringBuilder name;
    private StringBuilder version;
    @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) throwsSAXException {
        if ("app".equals(localName)) {
            Log.d("ContentHandler", "id is " + id.toString().trim());
            Log.d("ContentHandler", "name is " + name.toString().trim());
            Log.d("ContentHandler", "version is " + version.toString().trim());
            // 最后要将StringBuilder清空掉
            id.setLength(0);
            name.setLength(0);
            version.setLength(0);
        }
    }
    @Override
    public void endDocument() throws SAXException {
    }
}

可以看到,我们首先给 id、name和 version结点分别定义了一个 StringBuilder对象,并在 startDocument()方法里对它们进行了初始化。 每当开始解析某个结点的时候, startElement()方法就会得到调用,其中 localName参数记录着当前结点的名字,这里我们把它记录下来。接着在解析结点中具体内容的时候就会调用 characters()方法, 我们会根据当前的结点名进行判断,将解析出的内容添加到哪一个 StringBuilder对象中。最后在 endElement()方法中进行判断,如果 app结点已经解析完成,就打印出 id、name和 version的内容。需要注意的是,目前id、name和 version中都可能是包括回车或换行符的,因此在打印之前我们还需要调用一下 trim()方法,并且打印完成后还要将 StringBuilder的内容清空掉,不然的话会影响下一次内容的读取

解析XML:

try {
    SAXParserFactory factory = SAXParserFactory.newInstance();
    XMLReader xmlReader = factory.newSAXParser().getXMLReader();
    ContentHandler handler = new ContentHandler();
    // 将ContentHandler的实例设置到XMLReader中
    xmlReader.setContentHandler(handler);
    // 开始执行解析
    xmlReader.parse(new InputSource(new StringReader(xmlData)));
} catch (Exception e) {
    e.printStackTrace();
}

调用 parseXMLWithSAX()方法来解析 XML数据。parseXMLWithSAX()方法中先是创建了一个 SAXParserFactory的对象,然后再获取到XMLReader对象,接着将我们编写的 ContentHandler的实例设置到 XMLReader中,最后调用 parse()方法开始执行解析就好了。

 

最新文章

  1. PHP同时上传“多个”文件示例,并格式化$_FILES数组信息
  2. AMDJS编译工具
  3. DevExpress ChartControl大数据加载时有哪些性能优化方法
  4. PHP学习笔记:通过curl实现采集网站内容
  5. 关于stack around the variable “” was corrupted问题
  6. 1、程序启动原理和UIApplication【转】
  7. AngularJS Tabular Data with Edit/Update/Delete
  8. python 之路,Day27 - 主机管理+堡垒机系统开发
  9. STL容器介绍
  10. jQuery 自学笔记—8 常见操作
  11. 【转】Android 工程在4.0基础上混淆
  12. oracle表信息
  13. UVa 10954,Add All
  14. Java SpringBoot集成RabbitMq实战和总结
  15. Apache+php安装和配置 windows
  16. nowcoder172C 保护 (倍增lca+dfs序+主席树)
  17. BZOJ.1299.[LLH邀请赛]巧克力棒(博弈论 Nim)
  18. SpringMVC统一转换null值为空字符串的方法
  19. Autofac和nopcommerce中的Autofac, 还有反射
  20. mpvue上手教程

热门文章

  1. R语言内存管理
  2. 伪类before和after
  3. my97DatePicker日期控件——日期输入框联动,使用focus使第二个输入框没展示出日期控件
  4. Unity3d:UI面板管理整合进ToLua
  5. xml.etree.ElementTree对CDATA的输出
  6. 关于js单线程(转载)
  7. 关于call和apply函数的区别及用法
  8. java-sql注入攻击
  9. jQuery基础的工厂函数以及定时器的经典案例
  10. 使用Dotfuscator 进行.Net代码混淆 代码加密的方法