2012-04-09 3 views
1

Ich führe ein kleines Android-Projekt, das RSS/Atom Feed-Dokumente lesen konnte, mit SAX-Bibliothek. Alles funktioniert gut für Standard-RSS-Quellen, aber mit minimierten Quellen (ohne Leerzeichen oder neue Zeilen-Token) erzeugt es nichts als eine Liste von leeren Elementen. Meine Logs in Log cat zeigen auch nichts an. Ich überprüfe diese Probleme mit Varianten RSS-Sites, aber Probleme immer noch da. Unten ist mein Erbe Klasse von DefaultHandler, die ich den Parser Rss QuellenSAXParser fangen nichts mit minimiertem XML-Dokument

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

und Snippet zur Einrichtung zu behandeln verwenden:

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: Ich bin mit Android 2.3 x86 auf VirtualBox installiert für Debuggen, und diese Quellen funktionieren gut mit der integrierten RSS Reader-App, die mit der x86-Version geliefert wird. Also was ist hier falsch?

Antwort

1

Versuchen Sie mit _qName anstelle von _localName.

Ihr XML enthält CDATA, so dass Sie die XML-Antwort nicht mit Ihrem aktuellen Parser analysieren können. Sie müssen LexicalHandler zum Parsen von Raw HTML verwenden.

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

    } 

Sie können auch Ihre XML mit DOM analysieren, wenn Speicher nicht das Problem ist. Weitere Hilfe finden Sie unter Handling Lexical Events

+0

Können Sie die Beispiel-XML, die nicht funktioniert .. – Shehzad

+0

Immer noch nicht funktioniert, ein Beispiel für diesen Fall ist von [link] (http://genk.vn/trang-chu.rss) –

+0

Ich habe meine Antwort bearbeitet. – Shehzad