Android中XML解析

package com.example.thebroadproject;

public class Book {
    private int id;
    private String name;
    private float price;  

    public int getId() {
        return id;
    }  

    public void setId(int id) {
        this.id = id;
    }  

    public String getName() {
        return name;
    }  

    public void setName(String name) {
        this.name = name;
    }  

    public float getPrice() {
        return price;
    }  

    public void setPrice(float price) {
        this.price = price;
    }  

    public void addPrice(){
        price=price+1;
    }

    @Override
    public String toString() {
        return "id:" + id + ", name:" + name + ", price:" + price;
    }
}  

第一种:DOM。

DOM树所提供的随机访问方式给应用程序的开发带来了很大的灵活性,它可以任意地控制整个XML文档中的内容。然而,由于DOM分析器把整个XML文档转化成DOM树放在了内存中,因此,当文档比较大或者结构比较复杂时,对内存的需求就比较高。而且,对于结构复杂的树的遍历也是一项耗时的操作。所以,DOM分析器对机器性能的要求比较高,实现效率不十分理想。不过,由于DOM分析器所采用的树结构的思想与XML文档的结构相吻合,同时鉴于随机访问所带来的方便,因此,DOM分析器还是有很广泛的使用价值的。

package com.example.thebroadproject;

import java.io.InputStream;
import java.io.StringWriter;
import java.util.ArrayList;
import java.util.List;

import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.transform.OutputKeys;
import javax.xml.transform.Result;
import javax.xml.transform.Source;
import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.dom.DOMSource;
import javax.xml.transform.stream.StreamResult;

import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;

public class DomBookParser {

    public List<Book> parse(InputStream is) throws Exception {
        List<Book> books = new ArrayList<Book>();
        DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance(); // 取得DocumentBuilderFactory实例
        DocumentBuilder builder = factory.newDocumentBuilder(); // 从factory获取DocumentBuilder实例
        Document doc = builder.parse(is); // 解析输入流 得到Document实例
        Element rootElement = doc.getDocumentElement();
        NodeList items = rootElement.getElementsByTagName("book");
        for (int i = 0; i < items.getLength(); i++) {
            Book book = new Book();
            Node item = items.item(i);
            NodeList properties = item.getChildNodes();
            for (int j = 0; j < properties.getLength(); j++) {
                Node property = properties.item(j);
                String nodeName = property.getNodeName();
                if (nodeName.equals("id")) {
                    book.setId(Integer.parseInt(property.getFirstChild().getNodeValue()));
                } else if (nodeName.equals("name")) {
                    book.setName(property.getFirstChild().getNodeValue());
                } else if (nodeName.equals("price")) {
                    book.setPrice(Float.parseFloat(property.getFirstChild().getNodeValue()));
                }
            }
            books.add(book);
        }
        return books;
    }

    public String serialize(List<Book> books) throws Exception {
        DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
        DocumentBuilder builder = factory.newDocumentBuilder();
        Document doc = builder.newDocument(); // 由builder创建新文档

        Element rootElement = doc.createElement("books");

        for (Book book : books) {
            Element bookElement = doc.createElement("book");
            bookElement.setAttribute("id", book.getId() + "");

            Element nameElement = doc.createElement("name");
            nameElement.setTextContent(book.getName());
            bookElement.appendChild(nameElement);

            Element priceElement = doc.createElement("price");
            priceElement.setTextContent(book.getPrice() + "");
            bookElement.appendChild(priceElement);

            rootElement.appendChild(bookElement);
        }

        doc.appendChild(rootElement);

        TransformerFactory transFactory = TransformerFactory.newInstance();// 取得TransformerFactory实例
        Transformer transformer = transFactory.newTransformer(); // 从transFactory获取Transformer实例
        transformer.setOutputProperty(OutputKeys.ENCODING, "UTF-8"); // 设置输出采用的编码方式
        transformer.setOutputProperty(OutputKeys.INDENT, "yes"); // 是否自动添加额外的空白
        transformer.setOutputProperty(OutputKeys.OMIT_XML_DECLARATION, "no"); // 是否忽略XML声明

        StringWriter writer = new StringWriter();

        Source source = new DOMSource(doc); // 表明文档来源是doc
        Result result = new StreamResult(writer);// 表明目标结果为writer
        transformer.transform(source, result); // 开始转换

        return writer.toString();
    }

}

第二种:SAX的全称是Simple APIs for XML,也即XML简单应用程序接口。与DOM不同,SAX提供的访问模式是一种顺序模式,这是一种快速读写XML数据的方式。当使用SAX分析器对XML文档进行分析时,会触发一系列事件,并激活相应的事件处理函数,应用程序通过这些事件处理函数实现对XML文档的访问,因而SAX接口也被称作事件驱动接口。

package com.example.thebroadproject;

import java.io.InputStream;
import java.io.StringWriter;
import java.util.ArrayList;
import java.util.List;

import javax.xml.parsers.SAXParser;
import javax.xml.parsers.SAXParserFactory;
import javax.xml.transform.OutputKeys;
import javax.xml.transform.Result;
import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.sax.SAXTransformerFactory;
import javax.xml.transform.sax.TransformerHandler;
import javax.xml.transform.stream.StreamResult;

import org.xml.sax.Attributes;
import org.xml.sax.SAXException;
import org.xml.sax.helpers.AttributesImpl;
import org.xml.sax.helpers.DefaultHandler;

public class SaxBookParser {

    public List<Book> parse(InputStream is) throws Exception {
        SAXParserFactory factory = SAXParserFactory.newInstance(); // 取得SAXParserFactory实例
        SAXParser parser = factory.newSAXParser(); // 从factory获取SAXParser实例
        MyHandler handler = new MyHandler(); // 实例化自定义Handler
        parser.parse(is, handler); // 根据自定义Handler规则解析输入流
        return handler.getBooks();
    }

    public String serialize(List<Book> books) throws Exception {
        SAXTransformerFactory factory = (SAXTransformerFactory) TransformerFactory.newInstance();// 取得SAXTransformerFactory实例
        TransformerHandler handler = factory.newTransformerHandler(); // 从factory获取TransformerHandler实例
        Transformer transformer = handler.getTransformer(); // 从handler获取Transformer实例
        transformer.setOutputProperty(OutputKeys.ENCODING, "UTF-8"); // 设置输出采用的编码方式
        transformer.setOutputProperty(OutputKeys.INDENT, "yes"); // 是否自动添加额外的空白
        transformer.setOutputProperty(OutputKeys.OMIT_XML_DECLARATION, "no"); // 是否忽略XML声明

        StringWriter writer = new StringWriter();
        Result result = new StreamResult(writer);
        handler.setResult(result);

        String uri = ""; // 代表命名空间的URI 当URI无值时 须置为空字符串
        String localName = ""; // 命名空间的本地名称(不包含前缀) 当没有进行命名空间处理时 须置为空字符串

        handler.startDocument();
        handler.startElement(uri, localName, "books", null);

        AttributesImpl attrs = new AttributesImpl(); // 负责存放元素的属性信息
        char[] ch = null;
        for (Book book : books) {
            attrs.clear(); // 清空属性列表
            attrs.addAttribute(uri, localName, "id", "string", String.valueOf(book.getId()));// 添加一个名为id的属性(type影响不大,这里设为string)
            handler.startElement(uri, localName, "book", attrs); // 开始一个book元素 关联上面设定的id属性

            handler.startElement(uri, localName, "name", null); // 开始一个name元素 没有属性
            ch = String.valueOf(book.getName()).toCharArray();
            handler.characters(ch, 0, ch.length); // 设置name元素的文本节点
            handler.endElement(uri, localName, "name");

            handler.startElement(uri, localName, "price", null);// 开始一个price元素 没有属性
            ch = String.valueOf(book.getPrice()).toCharArray();
            handler.characters(ch, 0, ch.length); // 设置price元素的文本节点
            handler.endElement(uri, localName, "price");

            handler.endElement(uri, localName, "book");
        }
        handler.endElement(uri, localName, "books");
        handler.endDocument();

        return writer.toString();
    }

    // 需要重写DefaultHandler的方法
    private class MyHandler extends DefaultHandler {

        private List<Book> books;
        private Book book;
        private StringBuilder builder;

        // 返回解析后得到的Book对象集合
        public List<Book> getBooks() {
            return books;
        }

        @Override
        public void startDocument() throws SAXException {
            super.startDocument();
            books = new ArrayList<Book>();
            builder = new StringBuilder();
        }

        @Override
        public void startElement(String uri, String localName, String qName, Attributes attributes) throws SAXException {
            super.startElement(uri, localName, qName, attributes);
            if (localName.equals("book")) {
                book = new Book();
            }
            builder.setLength(0); // 将字符长度设置为0 以便重新开始读取元素内的字符节点
        }

        @Override
        public void characters(char[] ch, int start, int length) throws SAXException {
            super.characters(ch, start, length);
            builder.append(ch, start, length); // 将读取的字符数组追加到builder中
        }

        @Override
        public void endElement(String uri, String localName, String qName) throws SAXException {
            super.endElement(uri, localName, qName);
            if (localName.equals("id")) {
                book.setId(Integer.parseInt(builder.toString()));
            } else if (localName.equals("name")) {
                book.setName(builder.toString());
            } else if (localName.equals("price")) {
                book.setPrice(Float.parseFloat(builder.toString()));
            } else if (localName.equals("book")) {
                books.add(book);
            }
        }
    }
}

第三种 PULL解析XML是在Android中用到的比较多,而且Android已经将PULL技术集成到了系统中,所以在使用PULL的时候不需要额外的引入到jar,Android中要是使用上述的四种方式,需要引入额外的jar,当然JavaEE中使用PULL技术进行解析的话,就需要引入PULL所需的jar了,其实PULL技术和SAX技术差不多,Pull解析器和SAX解析器虽有区别但也有相似性。他们的区别为:SAX解析器的工作方式是自动将事件推入注册的事件处理器进行处理,因此你不能控制事件的处理主动结束;而Pull解析器的工作方式为允许你的应用程序代码主动从解析器中获取事件,正因为是主动获取事件,因此可以在满足了需要的条件后不再获取事件,结束解析。这是他们主要的区别。
而他们的相似性在运行方式上,Pull解析器也提供了类似SAX的事件,开始文档START_DOCUMENT和结束文档END_DOCUMENT,开始元素START_TAG和结束元素END_TAG,遇到元素内容TEXT等,但需要调用next() 方法提取它们(主动提取事件)。
Android系统中和Pull方式相关的包为org.xmlpull.v1,在这个包中提供了Pull解析器的工厂类XmlPullParserFactory和Pull解析器XmlPullParser,XmlPullParserFactory实例调用newPullParser方法创建XmlPullParser解析器实例,接着XmlPullParser实例就可以调用getEventType()和next()等方法依次主动提取事件,并根据提取的事件类型进行相应的逻辑处理。

package com.example.thebroadproject;

import java.io.InputStream;
import java.io.StringWriter;
import java.util.ArrayList;
import java.util.List;

import org.xmlpull.v1.XmlPullParser;
import org.xmlpull.v1.XmlSerializer;

import android.util.Xml;

public class PullBookParser {

    public List<Book> parse(InputStream is) throws Exception {
        List<Book> books = null;
        Book book = null;

        XmlPullParser parser = Xml.newPullParser(); // 由android.util.Xml创建一个XmlPullParser实例
        parser.setInput(is, "UTF-8"); // 设置输入流 并指明编码方式

        int eventType = parser.getEventType();
        while (eventType != XmlPullParser.END_DOCUMENT) {
            switch (eventType) {
            case XmlPullParser.START_DOCUMENT:
                books = new ArrayList<Book>();
                break;
            case XmlPullParser.START_TAG:
                if (parser.getName().equals("book")) {
                    book = new Book();
                } else if (parser.getName().equals("id")) {
                    eventType = parser.next();
                    book.setId(Integer.parseInt(parser.getText()));
                } else if (parser.getName().equals("name")) {
                    eventType = parser.next();
                    book.setName(parser.getText());
                } else if (parser.getName().equals("price")) {
                    eventType = parser.next();
                    book.setPrice(Float.parseFloat(parser.getText()));
                }
                break;
            case XmlPullParser.END_TAG:
                if (parser.getName().equals("book")) {
                    books.add(book);
                    book = null;
                }
                break;
            }
            eventType = parser.next();
        }
        return books;
    }

    public String serialize(List<Book> books) throws Exception {
        XmlSerializer serializer = Xml.newSerializer(); // 由android.util.Xml创建一个XmlSerializer实例
        StringWriter writer = new StringWriter();
        serializer.setOutput(writer); // 设置输出方向为writer
        serializer.startDocument("UTF-8", true);
        serializer.startTag("", "books");
        for (Book book : books) {
            serializer.startTag("", "book");
            serializer.attribute("", "id", book.getId() + "");

            serializer.startTag("", "name");
            serializer.text(book.getName());
            serializer.endTag("", "name");

            serializer.startTag("", "price");
            serializer.text(book.getPrice() + "");
            serializer.endTag("", "price");

            serializer.endTag("", "book");
        }
        serializer.endTag("", "books");
        serializer.endDocument();

        return writer.toString();
    }
}
时间: 2024-11-03 21:08:35

Android中XML解析的相关文章

Android中XML解析-Dom解析

Android中需要解析服务器端传过来的数据,由于XML是与平台无关的特性,被广泛运用于数据通信中,有的时候需要解析xml数据,格式有三种方式,分别是DOM.SAX以及PULL三种方式,本文就简单以Dom解析为例,解析XML, DOM方式解析xml是先把xml文档都读到内存中,然后再用DOM API来访问树形结构,并获取数据的,但是这样一来,如果xml文件很大,手机CPU处理能力比PC差,因此在处理效率方面就相对差了,使用Dom解析就不是太合适了. 基础维护 首先下assets目录下新建一个Bo

Android中XML解析-PULL解析

前面写了两篇XML解析的Dom和SAX方式,Dom比较符合思维方式,SAX事件驱动注重效率,除了这两种方式以外也可以使用Android内置的Pull解析器解析XML文件. Pull解析器的运行方式与 SAX 解析器相似,也是事件触发的.Pull解析方式让应用程序完全控制文档该怎么样被解析,比如开始和结束元素事件,使用parser.next()可以进入下一个元素并触发相应事件.通过Parser.getEventType()方法来取得事件的代码值,解析是在开始时就完成了大部分处理.事件将作为数值代码

Android中XML数据解析

转载请注明出处:http://blog.csdn.net/yegongheng/article/details/38296207 XML初步 今天我们来学习另一种非常重要的数据交换格式-XML.XML(Extensible Markup Language的缩写,意为可扩展的标记语言),它是一种元标记语言,即定义了用于定义其他特定领域有关语义的.结构化的标记语言,这些标记语言将文档分成许多部件并对这些部件加以标识.XML 文档定义方式有:文档类型定义(DTD)和XML Schema.DTD定义了文

Android学习xml解析大全之SAX和DOM

  随着android的学习解析xml成为了很多朋友面临的问.想学习如何解析xml就要先了解xml是什么. XML称为可扩展标记语言(Extensible Markup Language),由标准通用标记语言(SGML:Standard Generalized Markup Language)发展而来,允许开发者自定义标签,可以实现标签和内容的有效分离. 与HTML不同,XML不再侧重于数据如何表现,而是更多的关注数据如何存储和传输.因此,XML逐渐演变成为一种跨平台的数据交换格式.通过使用XM

C# 将XML格式字符串,写入数据集的表中 XML解析

将XML格式字符串,写入数据集的表1中 命名空间:using System.Xml; string strRead;//strRead为以下xml值 XmlDocument xd = new XmlDocument(); xd.LoadXml(strRead); XmlNodeList nodeList = xd.SelectSingleNode("root").ChildNodes;//获取bookstore节点的所有子节点 foreach (XmlNode xn in nodeLi

Android实现XML解析技术

http://www.cnblogs.com/hanyonglu/archive/2012/02/28/2370675.html http://weizhulin.blog.51cto.com/1556324/311678 Android实现XML解析技术

android 中Xml里面的id重名问题

情况一:同个一个Xml文件中的同名 在同个一个Xml文件的中若同名了,则前一个有效,而后一个无效 情况二:在不同的Xml 文件中的同名 在不同Xml文件的Id若同名了,两者都有效的. 当android的工程越来越大.xml文件越来越多时,避免不了两个xml文件中同 样的组件使用同样的id名字,gen目录下的R.java文件中,有关id的声明都在id的class中,即public static final class id{}:当两个xml文件中同样的组件,比如Button,有可能很多个文件中,都

Android中pull解析XML文件的简单使用

首先,android中解析XML文件有三种方式,dom,sax,pull 这里先讲pull,稍候会说SAX和DOM pull是一种事件驱动的xml解析方式,不需要解析整个文档,返回的值是数值型,是推荐的解析方式 看代码: XML文件 <?xml version="1.0" encoding="UTF-8"?> <persons> <person id="23"> <name>孙洋洋</name

Android中Pull解析器解析xml文件案例

首先 准备一个供解析的xml文件,这里我们假定要解析的文件名称为person.xml,文件的具体内容为: <?xml version="1.0" encoding="utf-8"?> <persons> <person id="23"> <name>liming</name> <age>23</age> </person> </persons&g