1

我正在运行一个小型 Android 项目,它可以使用 SAX 库读取 RSS/Atom Feed 文档。一切都适用于默认的 RSS 源,但是对于最小化的源(没有空格或换行符),它只会产生一个空白项目列表。我在 Log cat 中的日志也没有显示任何内容。我仔细检查了变体 RSS 站点的这个问题,但问题仍然存在。下面是我DefaultHandler用来处理 Rss 源的继承类

public class RssContentHandler extends DefaultHandler {
    private static final int UNKNOWN_STATE = -1;
    private static final int ELEMENT_START = 0;
    private static final int TITLE_END = 1;
    private static final int DESCRIPTION_END = 2;
    private static final int LINK_END = 3;
    private static final int PUBDATE_END = 4;
    private static final int CHANNEL_END = 5;

    private int iState = UNKNOWN_STATE;
    private String fullCharacters;
    private boolean itemFound = false;
    private RssItem rssItem;
    private RssFeed rssFeed;

    public RssContentHandler() {
    }

    public RssFeed getFeed() {
        return this.rssFeed;
    }

    @Override
    public void startDocument() {
        rssItem = new RssItem();
        rssFeed = new RssFeed();
        Log.i("startDocument", "startDocument");
    }

    @Override
    public void endDocument() {
    }

    @Override
    public void startElement(String _uri, String _localName, String _qName, Attributes _attributes) {
        if (_localName.equalsIgnoreCase("item")) {
            itemFound = true;
            rssItem = new RssItem();
            this.iState = UNKNOWN_STATE;
        } else
            this.iState = ELEMENT_START;
        fullCharacters = "";
    }

    @Override
    public void endElement(String _uri, String _localName, String _qName) {
        if (_localName.equalsIgnoreCase("item"))
            this.rssFeed.addItem(this.rssItem);
        else if (_localName.equalsIgnoreCase("title"))
            this.iState = TITLE_END;
        else if (_localName.equalsIgnoreCase("description"))
            this.iState = DESCRIPTION_END;
        else if (_localName.equalsIgnoreCase("link"))
            this.iState = LINK_END;
        else if (_localName.equalsIgnoreCase("pubDate"))
            this.iState = PUBDATE_END;
        else if (_localName.equalsIgnoreCase("channel"))
            this.iState = CHANNEL_END;
        else
            this.iState = UNKNOWN_STATE;
    }

    @Override
    public void characters(char[] _ch, int _start, int _length) {
        String strCharacters = new String(_ch, _start, _length);
        if (this.iState == ELEMENT_START)
            fullCharacters += strCharacters;
        else {
            if (!itemFound) {
                switch (this.iState) {
                case TITLE_END:
                    this.rssFeed.setTitle(fullCharacters);
                    break;
                case DESCRIPTION_END:
                    this.rssFeed.setDescription(fullCharacters);
                    break;
                case LINK_END:
                    this.rssFeed.setLink(fullCharacters);
                    break;
                case PUBDATE_END:
                    this.rssFeed.setPubDate(fullCharacters);
                    break;
                }
            } else {
                switch (this.iState) {
                case TITLE_END:
                    this.rssItem.setTitle(fullCharacters);
                    Log.i("characters", fullCharacters);
                    break;
                case DESCRIPTION_END:
                    this.rssItem.setDescription(fullCharacters);
                    break;
                case LINK_END:
                    this.rssItem.setLink(fullCharacters);
                    break;
                case PUBDATE_END:
                    this.rssItem.setPubDate(fullCharacters);
                    break;
                }
            }
            this.iState = UNKNOWN_STATE;            
        }
    }
}

和片段来设置解析器:

HttpClient client = new DefaultHttpClient();
    HttpGet request = new HttpGet();
    try {
        request.setURI(new URI(_strUrl));
    } catch (URISyntaxException e) {
        e.printStackTrace();
    }
    HttpResponse response = client.execute(request);
    Reader inputStream = new InputStreamReader(response.getEntity().getContent());
    RssContentHandler rssContentHandler = new RssContentHandler();
    InputSource inputSource = new InputSource();
    inputSource.setCharacterStream(inputStream);

    SAXParserFactory saxParserFactory = SAXParserFactory.newInstance();
    SAXParser saxParser = saxParserFactory.newSAXParser();
    saxParser.parse(inputSource, rssContentHandler);

    this.rssFeed = rssContentHandler.getFeed();

P/s:我正在使用安装在 VirtualBox 上的 Android 2.3 x86 进行调试,这些源代码可以与 x86 版本附带的内置 RSS 阅读器应用程序一起正常工作。那么这里有什么问题呢?

4

1 回答 1

1

尝试使用 _qName 而不是 _localName。

您的 xml 包含 CDATA,因此您无法使用当前解析器解析 XML 响应。您必须使用 LexicalHandler 来解析原始 HTML。

public class MyHandler implements LexicalHandler {

  public void startDTD(String name, String publicId, String systemId)
   throws SAXException {}
  public void endDTD() throws SAXException {}
  public void startEntity(String name) throws SAXException {}
  public void endEntity(String name) throws SAXException {}
  public void startCDATA() throws SAXException {}
  public void endCDATA() throws SAXException {}

  public void comment (char[] text, int start, int length)
   throws SAXException {

    String comment = new String(text, start, length);
    System.out.println(comment);

  }

如果内存不是问题,您还可以使用 DOM 解析 XML。如需更多帮助,请访问处理词汇事件

于 2012-04-09T06:27:56.383 回答