Fehler beim parsen eines Bildlinks mit XmlPullParser

  • Antworten:17
Gerhard P.
  • Forum-Beiträge: 46

12.01.2015, 14:14:23 via Website

Ich habe folgenden Code der Super funktioniert

private List readFeed(XmlPullParser parser, String rssLink, String autorpic) throws XmlPullParserException, IOException {
parser.require(XmlPullParser.START_TAG, null, "rss");
String title = null;
String link = null;
String pubDate = null;
String autor = null;
String autorimage = null;
String imageUrlContent = null;
String imageUrlDescription = null;
String imageUrl = null;

    List<RssItem> items = new ArrayList<>();
    Boolean readItemContent = false;

    while (parser.next() != XmlPullParser.END_DOCUMENT) {
        if (parser.getEventType() != XmlPullParser.START_TAG) {
            continue;
        }
        String name = parser.getName();
        if (name.equals("item")) {
            readItemContent = true;
        }
        if (readItemContent) {
            if (name.equals("title")) {
                String dirtTitle = readValue(parser, "title");
                {
                    title = cleanTitle(dirtTitle);
                }
            } else if (name.equals("link")) {
                link = readValue(parser, "link");
                //  Log.d("RssParserLink", "url: " + link);
            } else if (name.equals("pubDate")) {
                pubDate = readDate(parser);


            } else if (name.equals("description")) {

                // Parse the html description to get the image url
                String html = readValue(parser, "description");
                org.jsoup.nodes.Document docHtml = Jsoup.parse(html);
                Log.d("RssParserLink", "Des: "+ autor  + docHtml);
                Element imgElement = docHtml.select("img").first();
                if (imgElement != null){

                    imageUrlDescription = imgElement.attr("src");
                    Log.d("RssParserLink", "Imagendes: "+ autor + imageUrl);

                } else {

                    Log.d ("RssParserLink", "Kein Link" + autor );
                }


            }   else if (name.equals("content:encoded")) {      // name.equals("description")||name.equals("content:encoded")) {

                // Parse the html description to get the image url
                String html = readValue(parser, "content:encoded");

                org.jsoup.nodes.Document docHtml = Jsoup.parse(html);
                Log.d("RssParserLink", "Con: " + docHtml);
                Element imgElement = docHtml.select("img").first();
                if (imgElement != null){

                    imageUrlContent = imgElement.attr("src");

                    if (imageUrlContent != null) {
                        //  String imagenUrlDes = imageUrlContent;
                        Log.d("RssParserLink", "Imagendes: " + imageUrl);
                    }
                    //Log.d("RssParser", "url: " + imageUrlDescription);


                }


            }


            if (imageUrlDescription != null) {
                imageUrl = imageUrlDescription;
            } else {
                if (imageUrlContent != null) {
                    imageUrl = imageUrlContent;
                }

            }
        autor = new String(rssLink);
        autorimage = new String(autorpic);

        Log.d("RssParserLink", "RssItem: " + autor + imageUrl);


        }


        Log.d("sturmboard", "url: " + autor + pubDate);
        //  Log.d("sturmboard", "image: " + autorimage);

        if (title != null && link != null && pubDate != null) {

            RssItem item = new RssItem(title, link, pubDate, autor, autorimage, imageUrl);
            items.add(item);
            title = null;
            link = null;
            pubDate = null;
            autor = null;
            autorimage = null;
            imageUrl = null;


        }


    }
    return items;


}

Leider werden die "content:encoded" Links dem Falschem Item zugeteilt (immer dem folgenden ... und sollte das leer sein ... dann auch dem nächsten)..... hat wer eine Idee ... was da falsch ist?

Antworten
Pascal P.
  • Admin
  • Forum-Beiträge: 11.286

12.01.2015, 18:09:28 via Website

Hallo Gerhard,

List items = new ArrayList<>(); //Müsste in die <> nicht < RssItem> rein?

Und was meinst du dem falschen Item zugeteilt?
Ist dann der Content plötzlich in einem anderen RSS Item?
Du benutzt ja schon genung LogAusgaben, helfen diese nicht werter?

LG

— geändert am 12.01.2015, 18:09:41

LG Pascal //It's not a bug, it's a feature. :) ;)

Antworten
Gerhard P.
  • Forum-Beiträge: 46

12.01.2015, 20:50:59 via Website

um es Richtig zu Formulieren ....

Alles Läuft perfekt .... nur das Ergebnis von else if (name.equals("content:encoded")) { wird immer dem falschem Item zugeteilt!

Wenn Ich alles Säubere und nur titel / Link / pubDate / description auslese funktioniert auch alles .... wenn ich aber nur description gegen content:encoded tausche ..... ergeht die imageUrl an Falsche Items........

und ja ich bin Ratlos .......

Antworten
Pascal P.
  • Admin
  • Forum-Beiträge: 11.286

12.01.2015, 21:01:32 via App

Hast du mal den Link zum Feed mut dem du das Testest?

LG Pascal //It's not a bug, it's a feature. :) ;)

Antworten
Gerhard P.
  • Forum-Beiträge: 46

12.01.2015, 22:13:04 via Website

kommt per Nachricht

Antworten
Gerhard P.
  • Forum-Beiträge: 46

14.01.2015, 21:13:00 via Website

Auch sonst keiner eine Idee, woran es liegen könnte? Ich muss halt beide Tags "description" und "content:encoded" auslesen können ...

— geändert am 14.01.2015, 21:13:20

Antworten
Pascal P.
  • Admin
  • Forum-Beiträge: 11.286

14.01.2015, 21:16:30 via App

Zeig mal etwas mehr code dann kann ich das mal selber nachbauen und testen.

LG Pascal //It's not a bug, it's a feature. :) ;)

Antworten
Gerhard P.
  • Forum-Beiträge: 46

15.01.2015, 17:36:07 via Website

RSSHandler.class

import android.util.Log;
import android.util.Xml;

import org.jsoup.Jsoup;
import org.jsoup.nodes.Element;
import org.jsoup.select.Elements;
import org.xmlpull.v1.XmlPullParser;
import org.xmlpull.v1.XmlPullParserException;

import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.List;

public class RssHandler {

// We don't use namespaces
private final String ns = null;


public List<RssItem> parse(InputStream inputStream, String autorlink, String link2) throws XmlPullParserException, IOException {
    try {
        XmlPullParser parser = Xml.newPullParser();
        parser.setFeature(XmlPullParser.FEATURE_PROCESS_NAMESPACES, false);
        parser.setInput(inputStream, null);
        parser.nextTag();
        return readFeed(parser, autorlink, link2);
    } finally {
        inputStream.close();
    }
}

private List<RssItem> readFeed(XmlPullParser parser, String rssLink, String autorpic) throws XmlPullParserException, IOException {
    parser.require(XmlPullParser.START_TAG, null, "rss");
    String title = null;
    String link = null;
    String pubDate = null;
    String autor = null;
    String autorimage = null;
    String imageUrlContent = null;
    String imageUrlDescription = null;
    String imageUrl = null;


    List<RssItem> items = new ArrayList<RssItem>();
    Boolean readItemContent = false;

    while (parser.next() != XmlPullParser.END_DOCUMENT) {
        if (parser.getEventType() != XmlPullParser.START_TAG) {
            continue;
        }
        String name = parser.getName();
        if (name.equals("item")) {
            readItemContent = true;
        }
        if (readItemContent) {
            if (name.equals("title")) {
                String dirtTitle = readValue(parser, "title");
                {
                    title = cleanTitle(dirtTitle);
                    Log.d("RssParserLink", "HtmlContent: " + title);
                }

            } else if (name.equals("link")) {
                link = readValue(parser, "link");
                //  Log.d("RssParserLink", "url: " + link);
            } else if (name.equals("pubDate")) {
                pubDate = readDate(parser);


            } else if (name.equals("description")) {

                // Parse the html description to get the image url
                String html = readValue(parser, "description");
                org.jsoup.nodes.Document docHtml = Jsoup.parse(html);
                Log.d("RssParserLink", "Descript: " + docHtml);
                Element imgElement = docHtml.select("img").first();
                if (imgElement != null) {

                    imageUrlDescription = imgElement.attr("src");
                    Log.d("RssParserLink", "Imagendes: " + imageUrlDescription);
                    imageUrl = imageUrlDescription;
                } else {

                    Log.d("RssParserLink", "Kein LinkAAA" + autor);
                }


            }/* else if (name.equals("content:encoded")) { 

                // Parse the html description to get the image url
                String html = readValue(parser,"content:encoded");

                org.jsoup.nodes.Document docHtml = Jsoup.parse(html);

                Element imgElement2 = docHtml.select("img").first();
                if (imgElement2 != null) {


                    imageUrlContent = imgElement2.attr("src");

                } else {
                    Log.d("RssParserLink", "Kein LinkBBB" + autor);
                }


            }*/


        }

if (imageUrlDescription != null) {
imageUrl = imageUrlDescription;
} else {
if (imageUrlContent != null) {
imageUrl = imageUrlContent;
}

        }

        autor = new String(rssLink);
        autorimage = new String(autorpic);

       // Log.d("RssParserLink", "RssItemsTest: " + autor + imageUrl);


         if (title != null && link != null && pubDate != null) {

        RssItem item = new RssItem(title, link, pubDate, autor, autorimage, imageUrl);
             Log.d("RssParserLink", "RssItemsTest: " + autor + imageUrl);
        items.add(item);
        title = null;
        link = null;
        pubDate = null;
        autor = null;
        autorimage = null;
        imageUrl = null;


         }


    }
    return items;


}

private String cleanTitle(String str) {

    str = str.replace("&#x201E;", "");
    str = str.replace("&#x201C;", "");
    str = str.replace("&#xC4;", "Ä");
    str = str.replace("&#xD6;", "Ö");
    str = str.replace("&#xDC;", "Ü");
    str = str.replace("&#xDF;", "ß");
    str = str.replace("&#xE4;", "ä");
    str = str.replace("&#xF6;", "ö");
    str = str.replace("&#xFC;", "ü");
    str = str.replace("&#x1E9E;", "ß");
    str = str.replace("&quot;", "");
    str = str.replace("&#xe1;", "á");
    str = str.replace("&#xe4;", "ä");
    str = str.replace("&#xdf;", "ß");
    str = str.replace("&#xf6;", "ö");
    str = str.replace("&#xfc;", "ü");
    str = str.replace("&#x201c;", "“");
    str = str.replace("&#x201e;", "„");
    return str;
}

private String readValue(XmlPullParser parser, String key) throws XmlPullParserException, IOException {
    parser.require(XmlPullParser.START_TAG, ns, key);
    String link = readText(parser);
    parser.require(XmlPullParser.END_TAG, ns, key);
    return link;
}



private String readDate(XmlPullParser parser) throws XmlPullParserException, IOException {
    parser.require(XmlPullParser.START_TAG, ns, "pubDate");
    String date = readText(parser);
    DateFormat.parseDate(date.toString());
    parser.require(XmlPullParser.END_TAG, ns, "pubDate");
    return date;
}
// For the tags title and link, extract their text values.


private String readText(XmlPullParser parser) throws IOException, XmlPullParserException {
    String result = "";
    if (parser.next() == XmlPullParser.TEXT) {
        result = parser.getText();
        parser.nextTag();
    }
    return result;
}

private void skip(XmlPullParser parser) throws XmlPullParserException, IOException {
    if (parser.getEventType() != XmlPullParser.START_TAG) {
        throw new IllegalStateException();
    }
    int depth = 1;
    while (depth != 0) {
        switch (parser.next()) {
            case XmlPullParser.END_TAG:
                depth--;
                break;
            case XmlPullParser.START_TAG:
                depth++;
                break;
        }
    }
}

}

Antworten
Gerhard P.
  • Forum-Beiträge: 46

15.01.2015, 17:42:08 via Website

RssService.class

import android.app.IntentService;
import android.content.Context;
import android.content.Intent;
import android.content.SharedPreferences;
import android.os.Bundle;

import android.os.ResultReceiver;
import android.preference.PreferenceManager;
import android.support.v4.app.NotificationCompat;
import android.util.Log;

import org.xmlpull.v1.XmlPullParserException;

import java.io.IOException;
import java.io.InputStream;
import java.io.Serializable;
import java.net.URL;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Collections;
import java.util.Comparator;
import java.util.Date;
import java.util.List;
import java.util.Locale;
import java.util.TimeZone;

public class RssService extends IntentService implements Serializable {

private static final String RSS_LINK_1 = Irgendein link
private static final String RSS_LINK_2 = irgendein link


int image1 = R.drawable.rssapp;
int image2 = R.drawable.facebook;

public static final String ITEMS = "items";
public static final String RECEIVER = "receiver";

Tools tools;




public RssService() {
    super("RssService");
}


@Override
protected void onHandleIntent(Intent intent) {



    Log.d(Constants.TAG, "Service started");

    List<RssItem> rssItems = null;
    try {
        RssHandler parser = new RssHandler();
        rssItems = parser.parse(getInputStream(RSS_LINK_1), "Titel 1 ", String.valueOf(image1));
        rssItems.addAll(parser.parse(getInputStream(RSS_LINK_2), "Titel 2 ", String.valueOf(image2)));

        Collections.sort(rssItems, new CustomComparator());



    } catch (XmlPullParserException e) {
        Log.w(e.getMessage(), e);
    } catch (IOException e) {
        Log.w(e.getMessage(), e);
    }


    Bundle bundle = new Bundle();
    bundle.putSerializable(ITEMS, (Serializable) rssItems);
    ResultReceiver receiver = intent.getParcelableExtra(RECEIVER);
    receiver.send(0, bundle);


}




public class CustomComparator implements Comparator<RssItem> {


    public String cleanPub(String str) {
        str = str.replace(" +0000", "");
        str = str.replace("Dec", "12");
        str = str.replace("Nov", "11");
        str = str.replace("Oct", "10");
        str = str.replace("Sep", "09");
        str = str.replace("Aug", "08");
        str = str.replace("Jul", "07");
        str = str.replace("Jun", "06");
        str = str.replace("May", "05");
        str = str.replace("Apr", "04");
        str = str.replace("Mar", "03");
        str = str.replace("Feb", "02");
        str = str.replace("Jan", "01");
        str = str.replace(":", "");
        str = str.replace(" ", "");
        str = str.substring(4);
        return str;
    }

    @Override
    public int compare(RssItem o1, RssItem o2) {


        String[] formats = 
                {     //  "dMMyyyyHHmmss",
                        "ddMMyyyyHHmmss"// ,


                };
        for (String format : formats) {
            SimpleDateFormat sdf = new SimpleDateFormat(format);

            sdf.setTimeZone(TimeZone.getTimeZone("UTC"));


            try {

                Date date1 = sdf.parse(cleanPub(o1.getPublicationDate()));
                Date date2 = sdf.parse(cleanPub(o2.getPublicationDate()));
                return date2.compareTo(date1);
              /*  if (date2.before(date1))
                return -1;
                else if (date2.after(date1))
                  return +1; */

            } catch (ParseException ex) {
                Log.d("RssService", ex.getMessage());
            }


        }


        return 0;
    }
}

public InputStream getInputStream(String link) {
    try {
        URL url = new URL(link);
        return url.openConnection().getInputStream();
    } catch (IOException e) {
        Log.d("RssService", "Exception while retrieving the input stream", e);
        return null;
    }
}

Antworten
Gerhard P.
  • Forum-Beiträge: 46

15.01.2015, 17:43:27 via Website

RssItem.class

public class RssItem {

private final String title;
private final String link;
private final String pubDate;
private final String autor;
private final String autorimage;
private final String imageUrl;


public RssItem(String title, String link, String pubDate, String autor,String autorimage, String imageUrl) {
    this.title = title;
    this.link = link;
    this.pubDate = pubDate;
    this.autor = autor;
    this.autorimage = autorimage;
    this.imageUrl = imageUrl;

}


public String getTitle() {
    return title;
}

public String getLink() {
    return link;
}

public String getPublicationDate() {
    return pubDate;
}



public String getAutor() {
    return autor;
}

public String getAutorimage(){return autorimage;}

public String getImageUrl() {
    return imageUrl;
}

}

— geändert am 15.01.2015, 17:43:51

Antworten
Pascal P.
  • Admin
  • Forum-Beiträge: 11.286

15.01.2015, 19:01:14 via Website

Danke für den Code :)

Ich verstehe jetzt dein Problem aber nicht ,denn bei mir tut der Code :P

Du sagst dass dein Parser das content:encode Tag nicht parst, waurm??
Das funktionier doch:

else if (name.equals("content:encoded")) { 

                // Parse the html description to get the image url
                String html = readValue(parser,"content:encoded"); //Die HTML ist richtig und wird auch so angezeigt

                org.jsoup.nodes.Document docHtml = Jsoup.parse(html);

                Element imgElement2 = docHtml.select("img").first(); //Warum du allerdings das erste Bild parst weiss ich nicht
                if (imgElement2 != null) {


                    imageUrlContent = imgElement2.attr("src");

                } else {
                    Log.d("RssParserLink", "Kein LinkBBB" + autor);
                }


            }

Zudem gibst du die HTML nicht im LogCat aus, kann sein dass dich das verwirrt hat.
Ich sehe danähmlich kein Log.d() drin ausser beim Fehler.
Wenn du die Zeile hinzufügst wird dir die Content html in Code angezeigt:

    Log.d("RssParserLink", "HTML Content:  " + html);

LG Pascal //It's not a bug, it's a feature. :) ;)

Antworten
Gerhard P.
  • Forum-Beiträge: 46

18.01.2015, 21:36:34 via App

Das Problem ist, das die imageUrlContent dem Falschem Item (immer dem nächsten und teilweise dem übernächsten) zugeteilt wird......

Antworten
Pascal P.
  • Admin
  • Forum-Beiträge: 11.286

18.01.2015, 22:52:04 via Website

Das kann ich nicht bestätigen,bei mir werden die Bilder links richtig herausgeschreiben (sofern bild im rss vohanden)
Wenn kein Bild im RSS verfügbar ist kommt nur mist als Link raus, das ist ja aber nicht dein Problem.
Am besten du postest mal deine Testseite + LogCat etc. damit ich das nachvollziehen kann.
Soweit ich das im Code erkennen kann parst du immer nur daas 1. Bild heraus. Falls du alle Willst musst du dich lle img Tags iterieren.

PS: Brauchst mir keine PN schreiben, RSS feeds sind in der regel öffentlich ;)

Lg

— geändert am 18.01.2015, 22:53:09

LG Pascal //It's not a bug, it's a feature. :) ;)

Antworten
Gerhard P.
  • Forum-Beiträge: 46

19.01.2015, 16:36:27 via Website

hab in meiner Handler.class im Log.. folgendes geändert um mein Problem Verständlicher zu machen!

RssItem item = new RssItem(title, link, pubDate, autor, autorimage, imageUrl);
      ------>       Log.d("RssParserLink", "RssItemsTest: " + autor + title + imageUrl);  <------
        items.add(item);
        title = null;
        link = null;
        pubDate = null;
        autor = null;
        autorimage = null;
        imageUrl = null;

und dann kommt im Logcat unter dem Suchbegriff "RssItemsTest" das Raus:

     Sturm12 Epilog: Sturm12.at verabschiedet sichnull
     Sturm12 12 Momente:   Christopher, Didi und Jürgenhttp://www.sturm12.at/wp-content/uploads/10177915_10202716632569569_8573250731790600559_n-300x400.jpg
     Sturm12 12 Momente: Gordon, Peter und Ivan Sturm12 Sechs Jahre Sturm12.at in Zahlen 
     Sturm12 12 Momente: Julia, Peter und Andreashttp://www.sturm12.at/wp-content/uploads/diagramme-2-976x690.jpg
     Sturm12 12 Momente: Lukas, Werner und Daniel 
     Sturm12 Sturm12.at geht, die Statistik bleibt 
     Sturm12 12 legendäre Livetickerhttp://www.sturm12.at/wp-content/uploads/20140823-1035_1DCB5242-217x300.jpg
     Sturm12 12 legendäre  Fotoshttp://www.sturm12.at/wp-content/uploads/dsc_2368-500x332.jpg
     Sturm12 Torfabrik-Bonushttp://www.sturm12.at/wp-content/uploads/2009_Kharkiv.jpg

und hier zeigt sich schon der Fehler .... im Ersten Item ist der Link null ... was Falsch ist .... und der Link steht im nächsten Item!

siehe Feed: view-source:http://feeds.feedburner.com/Sturm12at?format=xml

egal was ich mache immer Falsch --- nur wenn ich im new RssItem if (imageUrl != null) bestimme ... kommts richtig .... dann fehlen aber die ganzen Items ohne Bilder ... was ja klar ist!

Also Ich hab keine Ahnung mehr!

— geändert am 19.01.2015, 16:37:57

Antworten
Pascal P.
  • Admin
  • Forum-Beiträge: 11.286

19.01.2015, 19:09:34 via Website

Der Fehler entsteht duch den meiner Meinung duch den etwas unstrukturieten Code.
Zudem macht der InputSream das ganze etwas schwierider, da du dann die while-Schleife brauchst, wennn du die XML alsString hättest dann könntest du einfach eine for-Schleife über alle Items laufen lassen etc..
Aber das nur nebenbei, zum Fehler:

Der Fehler kommt davon, weil du nicht weisst wann du den Block aufrufen musst:

   if (title != null && link != null && pubDate != null) {

    RssItem item = new RssItem(title, link, pubDate, autor, autorimage, imageUrl);

         Log.d("RssParserLink", "new RssItem: " + autor + title + imageUrl);

Dieser Teil des Codes wird schon vor dem parsen des Contents aufgerufen, da ja der titel, der Link und das pubDate gesetzt sind.
Da der parser aber noch nicht beim Content angelangt ist, kann er folglich die Image URL noch garnicht geparst haben-> imageurl = null
Da schaffen 2 boolean Vaiablen abhilfe:

   if (title != null && link != null && pubDate != null && descript &&content) {

    RssItem item = new RssItem(title, link, pubDate, autor, autorimage, imageUrl);

         Log.d("RssParserLink", "new RssItem: " + autor + title + imageUrl);//....

ich habe 2 neue booleans erstellt, die eine für die description und die andere für den Content.
In den entsprechenden ifs setze ich die Vars auf true und nach dem ausführen und erstellen eines RSSItems auf false zurück.
Dann tut alles so wie es soll.

Andere probleme können noch auftreten, z.b. was passiert wernn der Parser kein Bild findet etc.
Zudem würde ich dir empfehlen alle Bilder herauszuparsen, zur vollständigkeit.

Willst du eigentlich einen normalen RssReader programmieren oder hat das mit dem Bilderparsen einen Sinn?
Weil als normaler RSSRader kannst du auch einfach auf den normalen HTML Code zurückgreifen und musst dir die mühe mit den Bildern nicht machen.
LG

LG Pascal //It's not a bug, it's a feature. :) ;)

Antworten
Gerhard P.
  • Forum-Beiträge: 46

22.01.2015, 19:43:40 via App

  1. Das mit den Variablen hatte ich schon, dann fehlen aber alle Items ohne Bildlink... Dann würde auch ein != imageUrl reichen

  2. Ich hol mir die Bilder(falls vorhanden) um Sie als Titelbilder zu verwenden...

  3. Die Items sind dann nur eine Übersicht, der Aktuellen Artikel und verlinken auf die jeweilige Seite

— geändert am 22.01.2015, 19:48:43

Antworten
Pascal P.
  • Admin
  • Forum-Beiträge: 11.286

23.01.2015, 07:10:56 via App

Das ist relariv egal da immer ein Link da ist egal ob bild oder nicht. somit sollte der parser so passen obwohl sein code nich nicht optimal ist

LG Pascal //It's not a bug, it's a feature. :) ;)

Antworten