1

SAXライブラリを使用してRSS/Atomフィードドキュメントを読み取ることができる小さなAndroidプロジェクトを実行しています。デフォルトのRSSソースではすべてがうまく機能しますが、ソースを最小化すると(スペースや改行トークンなしで)、空白のアイテムのリストしか生成されません。Logcatのログにも何も表示されません。バリアント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

_localName の代わりに _qName を試してください。

xml に CDATA が含まれているため、現在のパーサーで XML 応答を解析できません。Raw HTML の解析には LexicalHandler を使用する必要があります。

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

  }

メモリが問題でない場合は、XML を DOM で解析することもできます。詳細については、レキシカル イベントの処理を参照してください。

于 2012-04-09T06:27:56.383 に答える