简体   繁体   中英

RSS / XML Parsing in BlackBerry

I am developing a RSS reader application where I need to read and display some parts of the data. Only title and link data needs to be extracted from the data fetched from the url, https://twitter.com/statuses/user_timeline/27756405.rss .

I am facing problem with parsing the xml, and need help on this issue.

My code is attached below.

public class RssMain extends UiApplication {
    RssMain theApp;

    public static void main(String[] args) {
        // create an instance of our app
        RssMain theApp = new RssMain();
        // "run" the app
        theApp.enterEventDispatcher();
    }

    // app constructor
    public RssMain() {
        // create an instance of the main screen of our application
        RssScreen screen = new RssScreen();
        // make the screen visible
        UiApplication.getUiApplication().pushScreen(screen);
    }

    class RssScreen extends MainScreen {

        public RssScreen() {
            String rssUrl = "http://twitter.com/statuses/user_timeline/27756405.rss";
            String[][] urlData = RSSHandler.getURLFromRSS(rssUrl);
            for (int i = 0; i < urlData.length; i++) {
                String title = urlData[0][i];
                String url = urlData[1][i];
                System.out.println("TITLE " + title);
                System.out.println("URL " + url);

            }
        }
    }
}


Implementation of RSSHandler

import java.io.IOException;
import java.io.InputStream;
import javax.microedition.io.Connector;
import javax.microedition.io.HttpConnection;
import javax.xml.parsers.ParserConfigurationException;
import javax.xml.parsers.SAXParser;
import javax.xml.parsers.SAXParserFactory;
import net.rim.blackberry.api.browser.Browser;
import net.rim.device.api.ui.component.LabelField;
import net.rim.device.api.util.Arrays;
import org.xml.sax.Attributes;
import org.xml.sax.SAXException;
import org.xml.sax.helpers.DefaultHandler;

class RSSHandler extends DefaultHandler {
    boolean isItem = false;
    boolean isTitle = false;
    boolean isLink = false;
    String[] title = new String[] {};
    String[] link = new String[] {};
    String value = "";

    public void startElement(String uri, String localName, String name, Attributes attributes) throws SAXException {
        if (!isItem) {
            if (name.equalsIgnoreCase("item"))
                isItem = true;
        } else {
            if (name.equalsIgnoreCase("title"))
                isTitle = true;
            if (name.equalsIgnoreCase("link"))
                isLink = true;
        }
    }

    public void characters(char[] ch, int start, int length) throws SAXException {
        if (isTitle || isLink) {
            value = value.concat(new String(ch, start, length));
        }
    }

    public void endElement(String uri, String localName, String name) throws SAXException {
        if (isItem && name.equalsIgnoreCase("item")) {
            isItem = false;
        }
        if (isTitle && name.equalsIgnoreCase("title")) {
            isTitle = false;
            Arrays.add(title, value);
            value = "";
        }
        if (isLink && name.equalsIgnoreCase("link")) {
            isLink = false;
            Arrays.add(link, value);
            value = "";
        }
    }

    public static String[][] getURLFromRSS(String url) {
        InputStream is = null;
        HttpConnection connection = null;
        RSSHandler rssHandler = new RSSHandler();
        try {
            connection = (HttpConnection) Connector.open(url);
            is = connection.openInputStream();
            try {
                SAXParser parser = SAXParserFactory.newInstance().newSAXParser();
                parser.parse(is, rssHandler);
            } catch (ParserConfigurationException e) {
                e.printStackTrace();
            } catch (SAXException e) {
                e.printStackTrace();
            } catch (IOException e) {
                e.printStackTrace();
            }
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            try {
                if (is != null)
                    is.close();
                if (connection != null)
                    connection.close();

            } catch (IOException e) {
                e.printStackTrace();
            }
        }
        String[][] result = new String[2][];
        result[0] = rssHandler.title;
        result[1] = rssHandler.link;
        return result;
    }
}

I've constructed a very rough application using pretty much the same principles as yours and it correctly loads the data from: http://twitter.com/statuses/user_timeline/27756405.rss

Please keep in mind this is just a very rough edit. I do not currently have access to blackberry development tools so I had converted this to a standalone java application but it should work fine if you alter it to fit in to your blackberry app. Note the switch from HttpConnection to URL in the parseRssData method, you may have to switch that back for blackberry.

RssMain

public class RssMain {
    public static final String DEFAULT_URL = "http://twitter.com/statuses/user_timeline/27756405.rss";

    public static void main( String[ ] args ) {
        RssItem[ ] items = parseRssData( DEFAULT_URL );
        for( RssItem item : items ) System.out.println( "Title: " + item.title( ) + " | Link: " + item.link( ) );
    }

    public static RssItem[ ] parseRssData( String url ) {
        URL u;
        InputStream in = null;
        RssHandler handler = new RssHandler( );

        try {
            u = new URL( url );
            in = u.openStream( );

            SAXParser parser = SAXParserFactory.newInstance( ).newSAXParser( );
            parser.parse( in, handler );
        } catch( Exception cause ) {
            cause.printStackTrace( );
        }

        return handler.items.toArray( new RssItem[ 0 ] );
    }
}

RssHandler

public class RssHandler extends DefaultHandler {
    public final ArrayList< RssItem > items;

    private boolean isItem = false;
    private boolean isTitle = false;
    private boolean isLink = false;

    String value = "";
    RssItem current = null;

    public RssHandler( ) {
        items = new ArrayList< RssItem >( );
    }

    @Override
    public void startElement( String uri, String localName, String name, Attributes attributes ) throws SAXException {
        if( !isItem  && name.equalsIgnoreCase( "item" ) ) isItem = true;
        else {
            if( name.equalsIgnoreCase( "title" ) ) isTitle = true;
            if( name.equalsIgnoreCase( "link" ) ) isLink = true;
        }
    }

    @Override
    public void endElement( String uri, String localName, String name ) {
        if( isItem && name.equalsIgnoreCase( "item" ) ) isItem = false;
        else if( isTitle || isLink ) {
            if( current == null ) current = new RssItem( );

            if( name.equalsIgnoreCase( "title" ) ) {
                isTitle = false;
                current.title( value );
            } else if( name.equalsIgnoreCase( "link" ) ) {
                isLink = false;
                current.link( value );
            }

            value = "";
            if( ( current.title( ) != null ) && ( current.link( ) != null ) ) {
                items.add( current );
                current = null;
            }
        }
    }

    @Override
    public void characters( char[ ] chars, int start, int length ) throws SAXException {
        if( isTitle || isLink ) value = value.concat( new String( chars, start, length ) );
    }
}

RssItem

public class RssItem {
    private String title;
    private String link;

    public String title( ) {
        return title;
    }

    public RssItem title( String title ) {
        this.title = title;
        return this;
    }

    public String link( ) {
        return link;
    }

    public RssItem link( String link ) {
        this.link = link;
        return this;
    }
}

This answer is based on this post, How to read XML file in Java – (DOM Parser) .

Source code of a complete BlackBerry application is added below which read, parse and show data from here, https://twitter.com/statuses/user_timeline/27756405.rss .

Data sample:

<?xml version="1.0" encoding="UTF-8"?>
<rss xmlns:georss="http://www.georss.org/georss" xmlns:atom="http://www.w3.org/2005/Atom" version="2.0" xmlns:twitter="http://api.twitter.com">
  <channel>
    <title>Twitter / LPProjekt</title>
    <link>http://twitter.com/LPProjekt</link>
    <atom:link type="application/rss+xml" rel="self" href="https://twitter.com/statuses/user_timeline/27756405.rss"/>
    <description>Twitter updates from Linkin Park Projekt / LPProjekt.</description>
    <language>en-us</language>
    <ttl>40</ttl>
  <item>
    <title>LPProjekt: LPP PSA: LPU will now cost a ridiculous $10/month ...</title>
    <description>LPProjekt: LPP PSA: LPU will now cost a ridiculous $10 ...</description>
    <pubDate>Thu, 19 Aug 2010 06:15:08 +0000</pubDate>
    <guid>http://twitter.com/LPProjekt/statuses/21555230077</guid>
    <link>http://twitter.com/LPProjekt/statuses/21555230077</link>
    <twitter:source>&lt;a href=&quot;http://www.digsby.com/?utm_campaign=twitter&quot; rel=&quot;nofollow&quot;&gt;Digsby&lt;/a&gt;</twitter:source>
    <twitter:place/>
  </item>
  <item>
    <title>LPProjekt: the instrumental from &quot;what ive done&quot; was j ...</title>
    <description>LPProjekt: the instrumental from &quot;what ive done&quot;  ...</description>
    <pubDate>Sun, 07 Feb 2010 23:34:26 +0000</pubDate>
    <guid>http://twitter.com/LPProjekt/statuses/8784251683</guid>
    <link>http://twitter.com/LPProjekt/statuses/8784251683</link>
    <twitter:source>&lt;a href=&quot;http://www.tweetdeck.com/&quot; rel=&quot;nofollow&quot;&gt;TweetDeck&lt;/a&gt;</twitter:source>
    <twitter:place/>
  </item>
  <item>
    <title>LPProjekt: a preview of the new linkinpark.com is now available ...</title>
    <description>LPProjekt: a preview of the new linkinpark.com is now  ...</description>
    <pubDate>Fri, 08 Jan 2010 22:20:53 +0000</pubDate>
    <guid>http://twitter.com/LPProjekt/statuses/7534555135</guid>
    <link>http://twitter.com/LPProjekt/statuses/7534555135</link>
    <twitter:source>&lt;a href=&quot;http://www.tweetdeck.com/&quot; rel=&quot;nofollow&quot;&gt;TweetDeck&lt;/a&gt;</twitter:source>
    <twitter:place/>
  </item>
  </channel>
</rss>



Example code

package mypackage;

import java.io.IOException;
import java.io.InputStream;
import java.util.Vector;

import javax.microedition.io.Connector;
import javax.microedition.io.StreamConnection;

import net.rim.device.api.ui.UiApplication;
import net.rim.device.api.ui.component.LabelField;
import net.rim.device.api.ui.component.SeparatorField;
import net.rim.device.api.ui.container.MainScreen;
import net.rim.device.api.ui.container.VerticalFieldManager;
import net.rim.device.api.xml.parsers.DocumentBuilder;
import net.rim.device.api.xml.parsers.DocumentBuilderFactory;

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

public class MyApp extends UiApplication {

    public static void main(String[] args) {
        (new MyApp()).enterEventDispatcher();
    }

    public MainScreen screen = new MainScreen();

    public MyApp() {
        pushScreen(screen);
        (new Connection()).start();
    }

    private class Connection extends Thread {
        private Vector listElements = new Vector();
        private static final String RSS_FEED_URL = "https://twitter.com/statuses/user_timeline/27756405.rss";
        private static final String CONNECTION_PARAMS = ";deviceside=true";

        public void run() {
            StreamConnection conn = null;
            InputStream is = null;
            try {
                conn = (StreamConnection) Connector.open(RSS_FEED_URL + CONNECTION_PARAMS);

                DocumentBuilderFactory docBuilderFactory = DocumentBuilderFactory.newInstance();
                docBuilderFactory.setIgnoringElementContentWhitespace(true);
                docBuilderFactory.setCoalescing(true);
                DocumentBuilder docBuilder = docBuilderFactory.newDocumentBuilder();
                is = conn.openInputStream();
                Document doc = docBuilder.parse(is);
                doc.getDocumentElement().normalize();

                NodeList itemNodeList = doc.getElementsByTagName("item");
                for (int index = 0; index < itemNodeList.getLength(); index++) {
                    Node nNode = itemNodeList.item(index);
                    if (nNode.getNodeType() == Node.ELEMENT_NODE) {
                        Element itemElement = (Element) nNode;

                        // Extract desired data here
                        System.out.println("title : " + getTagValue("title", itemElement));
                        System.out.println("description : " + getTagValue("description", itemElement));
                        System.out.println("pubDate : " + getTagValue("pubDate", itemElement));
                        System.out.println("guid : " + getTagValue("guid", itemElement));
                        System.out.println("link : " + getTagValue("link", itemElement));

                        listElements.addElement(getTagValue("title", itemElement));
                        listElements.addElement(getTagValue("link", itemElement));
                    }
                }

            } catch (Exception e) {
            } finally {
                if (is != null) { try { is.close(); } catch (IOException ignored) { } }
                if (conn != null) { try { conn.close(); } catch (IOException ignored) { } }
            }

            showData();
        }

        private String getTagValue(String sTag, Element eElement) {
            NodeList nlList = eElement.getElementsByTagName(sTag).item(0).getChildNodes();
            Node nValue = (Node) nlList.item(0);
            return nValue.getNodeValue();
        }

        private void showData() {
            UiApplication.getUiApplication().invokeLater(new Runnable() {
                public void run() {
                    for (int i = 0; listElements != null && i < listElements.size(); i += 2) {
                        VerticalFieldManager vfm = new VerticalFieldManager();
                        vfm.setMargin(10, 10, 10, 10);
                        vfm.add(new LabelField("Item no. " + ((i / 2) + 1)));
                        vfm.add(new LabelField("Title: " + listElements.elementAt(i)));
                        vfm.add(new LabelField("Link: " + listElements.elementAt(i + 1)));
                        vfm.add(new SeparatorField( SeparatorField.LINE_HORIZONTAL));

                        screen.add(vfm);
                    }
                    screen.invalidate();
                }
            });
        }
    }
}



Output in Simulator

Output in Simulator

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM