The use of XML in the Android

XML parser
Java-Simple API for XML (SAX) and Document Object Model (DOM) are available on the Android. The Java API for many years has been a part of technology. Relatively new Streaming API for XML (StAX) in Android, are not available. However, Android provides a functionally equivalent library. Finally, Java XML Binding API in Android, not available. The API has been confirmed to be implemented in Android. However, it is more likely to be a heavyweight API, need to use many different instances of the class to represent the XML document. Therefore, it is limited for the environment, such as handheld devices for Android, not ideal.

Basic feed parser class

public abstract class BaseFeedParser implements FeedParser {

    // names of the XML tags
    static final String PUB_DATE = "pubDate";
    static final  String DESCRIPTION = "description";
    static final  String LINK = "link";
    static final  String TITLE = "title";
    static final  String ITEM = "item";

    final URL feedUrl;

    protected BaseFeedParser(String feedUrl){
        try {
            this.feedUrl = new URL(feedUrl);
        } catch (MalformedURLException e) {
            throw new RuntimeException(e);
        }
    }

    protected InputStream getInputStream() {
        try {
            return feedUrl.openConnection().getInputStream();
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
    }
}

Sample XML feed


<?xml version="1.0" encoding="UTF-8"?>

<!-- generator="FeedCreator 1.7.2" -->

<rss version="2.0">

  <channel>

    <title>android_news</title>

    <description>android_news</description>

    <link>http://www.androidster.com/android_news.php</link>

    <lastBuildDate>Sun, 19 Apr 2009 19:43:45 +0100</lastBuildDate>

    <generator>FeedCreator 1.7.2</generator>

    <item>

      <title>Samsung S8000 to Run Android, Play DivX, Take Over the
World</title>

      <link>http://www.androidster.com/android_news/samsung-s8000-to-run-android-
play-divx-take-over-the-world</link>

      <description>More details have emerged on the first Samsung handset
to run Android. A yet-to-be announced phone called the S8000 is being
reported ...</description>

      <pubDate>Thu, 16 Apr 2009 07:18:51 +0100</pubDate>

    </item>

    <item>

      <title>Android Cupcake Update on the Horizon</title>

      <link>http://www.androidster.com/android_news/android-cupcake-update-
on-the-horizon</link>

      <description>After months of discovery and hearsay, the Android
build that we have all been waiting for is about to finally make it
out ...</description>

      <pubDate>Tue, 14 Apr 2009 04:13:21 +0100</pubDate>

    </item>

  </channel>

</rss>

Use SAX

SAX implementation


public class SaxFeedParser extends BaseFeedParser {

    protected SaxFeedParser(String feedUrl){
        super(feedUrl);
    }

    public List<Message> parse() {
        SAXParserFactory factory = SAXParserFactory.newInstance();
        try {
            SAXParser parser = factory.newSAXParser();
            RssHandler handler = new RssHandler();
            parser.parse(this.getInputStream(), handler);
            return handler.getMessages();
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
    }
}

SAX handlers

import static org.developerworks.android.BaseFeedParser.*;

public class RssHandler extends DefaultHandler{
    private List<Message> messages;
    private Message currentMessage;
    private StringBuilder builder;

    public List<Message> getMessages(){
        return this.messages;
    }
    @Override
    public void characters(char[] ch, int start, int length)
            throws SAXException {
        super.characters(ch, start, length);
        builder.append(ch, start, length);
    }

    @Override
    public void endElement(String uri, String localName, String name)
            throws SAXException {
        super.endElement(uri, localName, name);
        if (this.currentMessage != null){
            if (localName.equalsIgnoreCase(TITLE)){
                currentMessage.setTitle(builder.toString());
            } else if (localName.equalsIgnoreCase(LINK)){
                currentMessage.setLink(builder.toString());
            } else if (localName.equalsIgnoreCase(DESCRIPTION)){
                currentMessage.setDescription(builder.toString());
            } else if (localName.equalsIgnoreCase(PUB_DATE)){
                currentMessage.setDate(builder.toString());
            } else if (localName.equalsIgnoreCase(ITEM)){
                messages.add(currentMessage);
            }
            builder.setLength(0);
        }
    }

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

    @Override
    public void startElement(String uri, String localName, String name,
            Attributes attributes) throws SAXException {
        super.startElement(uri, localName, name, attributes);
        if (localName.equalsIgnoreCase(ITEM)){
            this.currentMessage = new Message();
        }
    }
}

Android SDK provides a utility class named android.util.Xml. Android SAX parser

public class AndroidSaxFeedParser extends BaseFeedParser {

    public AndroidSaxFeedParser(String feedUrl) {
        super(feedUrl);
    }

    public List<Message> parse() {
        RssHandler handler = new RssHandler();
        try {
            Xml.parse(this.getInputStream(), Xml.Encoding.UTF_8, handler);
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
        return handler.getMessages();
    }

}

Simplified Android SAX parser

public class AndroidSaxFeedParser extends BaseFeedParser {

    public AndroidSaxFeedParser(String feedUrl) {
        super(feedUrl);
    }

    public List<Message> parse() {
        final Message currentMessage = new Message();
        RootElement root = new RootElement("rss");
        final List<Message> messages = new ArrayList<Message>();
        Element channel = root.getChild("channel");
        Element item = channel.getChild(ITEM);
        item.setEndElementListener(new EndElementListener(){
            public void end() {
                messages.add(currentMessage.copy());
            }
        });
        item.getChild(TITLE).setEndTextElementListener(new EndTextElementListener(){
            public void end(String body) {
                currentMessage.setTitle(body);
            }
        });
        item.getChild(LINK).setEndTextElementListener(new EndTextElementListener(){
            public void end(String body) {
                currentMessage.setLink(body);
            }
        });
        item.getChild(DESCRIPTION).setEndTextElementListener(new EndTextElementListener(){
            public void end(String body) {
                currentMessage.setDescription(body);
            }
        });
        item.getChild(PUB_DATE).setEndTextElementListener(new EndTextElementListener(){
            public void end(String body) {
                currentMessage.setDate(body);
            }
        });
        try {
            Xml.parse(this.getInputStream(), Xml.Encoding.UTF_8, root.getContentHandler());
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
        return messages;
    }
}

The new code does not use SAX SAX parsing process, but the use of the SDK in the android.sax package classes. These classes allow you to build the structure of XML documents, and according to need to add event listener. In the above code, you declare that the document will have a rss root element, and it has a channel sub-elements. Then, you will have an ITEM declaration channel child element, and start adding the listener. For each listener, you are using an implementation of a specific interface (EndElementListner or EndTextElementListener) of anonymous inner classes. Note that you do not need to track the character data. Not only because it will be more simple, more importantly, more efficient. Finally, call the Xml.parse practical approach, you will pass through the root element of a process generated

Use DOM
The feed parser implementation based on DOM

public class DomFeedParser extends BaseFeedParser {

    protected DomFeedParser(String feedUrl) {
        super(feedUrl);
    }

    public List<Message> parse() {
        DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
        List<Message> messages = new ArrayList<Message>();
        try {
            DocumentBuilder builder = factory.newDocumentBuilder();
            Document dom = builder.parse(this.getInputStream());
            Element root = dom.getDocumentElement();
            NodeList items = root.getElementsByTagName(ITEM);
            for (int i=0;i<items.getLength();i++){
                Message message = new Message();
                Node item = items.item(i);
                NodeList properties = item.getChildNodes();
                for (int j=0;j<properties.getLength();j++){
                    Node property = properties.item(j);
                    String name = property.getNodeName();
                    if (name.equalsIgnoreCase(TITLE)){
                        message.setTitle(property.getFirstChild().getNodeValue());
                    } else if (name.equalsIgnoreCase(LINK)){
                        message.setLink(property.getFirstChild().getNodeValue());
                    } else if (name.equalsIgnoreCase(DESCRIPTION)){
                        StringBuilder text = new StringBuilder();
                        NodeList chars = property.getChildNodes();
                        for (int k=0;k<chars.getLength();k++){
                            text.append(chars.item(k).getNodeValue());
                        }
                        message.setDescription(text.toString());
                    } else if (name.equalsIgnoreCase(PUB_DATE)){
                        message.setDate(property.getFirstChild().getNodeValue());
                    }
                }
                messages.add(message);
            }
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
        return messages;
    }
}

XML pull parser
Android does not provide support for Java StAX API. However, Android does comes with a pull parser, which works similar to StAX. It allows your application code to retrieve events from the parser, which automatically SAX parser event handler into the opposite
Pull parser implementation based on

public class XmlPullFeedParser extends BaseFeedParser {
    public XmlPullFeedParser(String feedUrl) {
        super(feedUrl);
    }
    public List<Message> parse() {
        List<Message> messages = null;
        XmlPullParser parser = Xml.newPullParser();
        try {
            // auto-detect the encoding from the stream
            parser.setInput(this.getInputStream(), null);
            int eventType = parser.getEventType();
            Message currentMessage = null;
            boolean done = false;
            while (eventType != XmlPullParser.END_DOCUMENT && !done){
                String name = null;
                switch (eventType){
                    case XmlPullParser.START_DOCUMENT:
                        messages = new ArrayList<Message>();
                        break;
                    case XmlPullParser.START_TAG:
                        name = parser.getName();
                        if (name.equalsIgnoreCase(ITEM)){
                            currentMessage = new Message();
                        } else if (currentMessage != null){
                            if (name.equalsIgnoreCase(LINK)){
                                currentMessage.setLink(parser.nextText());
                            } else if (name.equalsIgnoreCase(DESCRIPTION)){
                                currentMessage.setDescription(parser.nextText());
                            } else if (name.equalsIgnoreCase(PUB_DATE)){
                                currentMessage.setDate(parser.nextText());
                            } else if (name.equalsIgnoreCase(TITLE)){
                                currentMessage.setTitle(parser.nextText());
                            }
                        }
                        break;
                    case XmlPullParser.END_TAG:
                        name = parser.getName();
                        if (name.equalsIgnoreCase(ITEM) && currentMessage != null){
                            messages.add(currentMessage);
                        } else if (name.equalsIgnoreCase(CHANNEL)){
                            done = true;
                        }
                        break;
                }
                eventType = parser.next();
            }
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
        return messages;
    }
}

pull parser and SAX parser similar to the operation mode. It provides similar events (start element and end element), but you need to use (parser.next () extract them. The event will be sent as a numeric code, so you can use a simple case-switch. Note that the resolution did not SAX parsing as Jianting elements like the end, but completed most of the beginning of treatment. in the code, when an element starts, you can call parser.nextText () from the XML document to extract all character data. Haixu Note that you set a flag (Boolean variable done) to determine when the contents reach the end of some interest. It allows you to read the XML document to stop early because you know the code will not care about the rest of the document. This is sometimes very practical, especially when you only need to access a small part of the XML document. by Jinkuai stop parsing, you can greatly reduce the analysis time. This optimized for connection of mobile devices is particularly slow Important. Pull parser can provide some performance advantages and ease of use. It can also be used to write XML.

Creating XML
XML pull parser written using

private String writeXml(List<Message> messages){
    XmlSerializer serializer = Xml.newSerializer();
    StringWriter writer = new StringWriter();
    try {
        serializer.setOutput(writer);
        serializer.startDocument("UTF-8", true);
        serializer.startTag("", "messages");
        serializer.attribute("", "number", String.valueOf(messages.size()));
        for (Message msg: messages){
            serializer.startTag("", "message");
            serializer.attribute("", "date", msg.getDate());
            serializer.startTag("", "title");
            serializer.text(msg.getTitle());
            serializer.endTag("", "title");
            serializer.startTag("", "url");
            serializer.text(msg.getLink().toExternalForm());
            serializer.endTag("", "url");
            serializer.startTag("", "body");
            serializer.text(msg.getDescription());
            serializer.endTag("", "body");
            serializer.endTag("", "message");
        }
        serializer.endTag("", "messages");
        serializer.endDocument();
        return writer.toString();
    } catch (Exception e) {
        throw new RuntimeException(e);
    }
}

XmlSerializer class is xml parsing it with a pull XmlPullParser used part of the package. It does not extract the event, but released them into the data stream or writing program. In this case, it only pushed the event of a java.io.StringWriter instance. It provides an intuitive API, through various methods start and end document processing elements and add text or attribute. This is an excellent replacement StringBuilder program, because it can more easily ensure that your XML has a good structure.

分类:Mobile 时间:2011-01-03 人气:154
分享到:
blog comments powered by Disqus

相关文章

  • XML Document Object Model (DOM) 2010-03-28

    XML Document Object Model (DOM) Be able to programmatically read, process and modify the XML document. XPath expression XPath expressions using the path notation (with the URL path notation used similar) addressing parts of XML documents. Expression

  • Java6.0 new features of StAX - a comprehensive analysis of Java XML parsing technologies 2010-04-21

    Mustang (Mustang, Java 6.0 code) compared to Tiger (Tiger, Java 5.0, code-named) who, from the performance improvements, scripting languages (Javascript, JRuby, Groovy) the support of the extension of java.io.File to the desktop applications enhance

  • java, xml 2010-03-29

    /* * To change this template, choose Tools | Templates * and open the template in the editor. * Reading an XML file */ package util.xml; import java.io.*; import java.util.Vector; import java.util.logging.Level; import java.util.logging.Logger; impor

  • JAVA XML file to read data (transfer) 2010-04-13

    <? Xml version = "1.0" encoding = "UTF-8 "?><! DOCTYPE managers SYSTEM" manager-config.dtd "> <managers> <manager name="DBConnectionManager"> <service> net.csdn.blog. xport.IDBConnectio

  • JAVA XML parsing approach DOM.SAX.DOM4J.JDOM.StAX Illustration and comparison of 2010-06-05

    1. Wapakhabulo in various ways 1) DOM (JAXP Crimson parser) DOM is platform-and language-independent manner, said the official W3C standard XML document. DOM is a hierarchical organization of nodes or pieces of information collection. This hierarchy

  • (Original) java xml data access WebService returns an instance of students into the local file 2010-06-17

    Reprinted please indicate the source: http://eric-619.javaeye.com/blog/692838 import java.io.IOException; import java.io.InputStream; import java.net.MalformedURLException; import java.net.URL; import java.net.URLConnection; import java.io.FileNotFou

  • java xml parsing and import database (dom4j) 2010-07-11

    java xml parsing and import database (dom4j) import java.io.File; import java.sql.Connection; import java.sql.PreparedStatement; import java.sql.ResultSet; import java.util.Iterator; import java.util.List; import org.dom4j.Document; import org.dom4j.

  • java xml files and do database analysis of response data or results of operations of the class (help out) 2010-08-22

    You to review the trial: Use hibernate in the pojo object to table mapping. c + + client and java web server via http post xml file interactive (servlet). Some people will say why I do not webservice. Because I felt bad c + + client host soap protoco

  • Java, XML parsing techniques of four 2010-10-28

    In routine work, will inevitably encounter the XML as a data storage format. Faced with a wide variety of solutions, which best for us? In this article, I am one of four major programs do not fully evaluation, just to test this for traversing XML, be

  • Java + XML + MVC Framework StrutsCX Profile 2010-03-29

    Java + XML + MVC Framework StrutsCX Profile StrutsCX is a Struts-based framework for XML solutions, and the Struts different, it uses XML (or rather XSLT) as a presentation layer, rather than Struts is JSP as a presentation layer. Currently, it's the

iOS 开发

Android 开发

Python 开发

JAVA 开发

开发语言

PHP 开发

Ruby 开发

搜索

前端开发

数据库

开发工具

开放平台

Javascript 开发

.NET 开发

云计算

服务器

Copyright (C) codeweblog.com, All Rights Reserved.

CodeWeblog.com 版权所有 黔ICP备15002463号-1

processed in 0.439 (s). 14 q(s)