The use of XML in the Android

sponsored links
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.
  • del.icio.us
  • StumbleUpon
  • Digg
  • TwitThis
  • Mixx
  • Technorati
  • Facebook
  • NewsVine
  • Reddit
  • Google
  • LinkedIn
  • YahooMyWeb

Related Posts of The use of XML in the Android

  • JAVA EE JSP_JNDI

    dsfdsa http://lindows.javaeye.com/admin/blogs/213348 Tomcat 6 with the connection pool data source configuration http://www.blogjava.net/ec2008/archive/2008/07/19/216063.html project: test Driver path: D: \ workspace \ test \ WebRoot \ WEB-INF \ lib ...

  • Hibernate connection pool configuration

    Hibernate connection pool configuration <! - Jdbc -> <property name="connection.driver_class"> oracle.jdbc.driver.OracleDriver </ property> <property name="connection.url"> jdbc: oracle: thin: @ 10.203.14.132:15

  • Hibernate.cfg.xml configuration file (including the primary key generation strategy Introduction)

    Hibernate.cfg.xml configuration file: <? xml version = "1.0" encoding = "utf-8"?> <! DOCTYPE hibernate-configuration PUBLIC "- / / Hibernate / Hibernate Configuration DTD / / EN" "hibernate-configuration-2.0.dtd

  • The EJB3 Persistence

    EJB3 persistence with Hibernate is very similar to the mechanism: Environment: Server: JBOSS5.0 Database: MySQL5.0 1. Set up a data source First of all, in jboss-5.0.0.GA \ server \ default \ deploy, the establishment of a database used to connect the dat

  • Servlet brief introduction

    Servlet brief introduction: Servlet is a small application server Are used to complete the B / S architecture, the client requests the response to treatment Platform independence, performance, able to run thread Servlet API for Servlet provides the s ...

  • Spring2.0 + hibernate3.1 + log4j + mysql demo

    applicationContext.xml Non-attachment jar package, necessary friends can send an email to todd.liangt @ gmail.com

blog comments powered by Disqus
Recent
Recent Entries
Tag Cloud
Random Entries