1

我正在开发一个 RSS 阅读器应用程序,我需要在其中读取和显示部分数据。仅需要从从 url 获取的数据中提取数据,titlehttps ://twitter.com/statuses/user_timeline/27756405.rsslink

我在解析 xml 时遇到问题,在这个问题上需要帮助。

我的代码附在下面。

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);

            }
        }
    }
}


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;
    }
}
4

2 回答 2

2

我使用与您的原理几乎相同的原理构建了一个非常粗糙的应用程序,并且它正确地从以下位置加载数据:http: //twitter.com/statuses/user_timeline/27756405.rss

请记住,这只是一个非常粗略的编辑。我目前无法访问黑莓开发工具,因此我已将其转换为独立的 Java 应用程序,但如果您将其更改为适合您的黑莓应用程序,它应该可以正常工作。请注意 parseRssData 方法中从 HttpConnection 到 URL 的切换,对于黑莓,您可能必须将其切换回。

主程序

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;
    }
}
于 2012-09-08T08:43:59.633 回答
2

这个答案基于这篇文章,如何在 Java 中读取 XML 文件 - (DOM Parser)

下面添加了完整 BlackBerry 应用程序的源代码,该应用程序从此处读取、解析和显示数据,https://twitter.com/statuses/user_timeline/27756405.rss

数据样本:

<?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>



示例代码

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();
                }
            });
        }
    }
}



模拟器中的输出

模拟器中的输出

于 2012-09-08T08:59:36.437 回答