XML Parsen via XPath

  • 7 Antworten
  • Letztes Antwortdatum
T

tito286

Neues Mitglied
0
Hallo allerseits,

ich bin absolut neu in der Android App Entwicklung und möchte eine App, die mir bestimmte Texte einer HTML Seite ausgibt.
Habe über ein Tutorial (Wetterapp) eine Code gefunden der an sich funktioniert. Jedoch nicht bei jeder (HTML)Seite.

Vorweg: Das die Baumstruktur der HTML Datei für dieses Programm eindeutig sein muss ist mir klar. Die App ist eigentlich für WetterAPIs gedacht, daher nicht wundern dass ich einen Teil per // rausgenommen hab.

Hier die ersten Zeilen in XML der Seite bei der es klappt:

<!--?xml version="1.0" encoding="utf-8"?-->
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html lang="en" xmlns="http://www.w3.org/1999/xhtml" xml:lang="en">
<head> … </head>

Hier kann ich problemlos über den Pfad in XML(z.B.: html/) ein Item (z.B.: "lang") ausgeben lassen.

Bei folgender Seite haut das nicht hin obwohl der XML Text als String eingelesen wird:

<!DOCTYPE html>
<html lang="de-de" dir="ltr">

<head> … </head>

Habe einige Versuche gemacht aber es klappt nicht. Habe C/C++ Grundkenntnisse aber was JAVA & (und vor allem) HTML angeht, bin ich unbedarft.

Hat jemand hierzu eine Idee bzw. Lösungsvorschläge?

Vielen Dank im Voraus!

hier noch der wesentliche Teil des Codes...

Code:
  public void btnSearchClick(View view)
    {
            if(texteingabe.getText().length() < 3 )
            {
                textausgabe.setText("Stadt angeben ... ");
            }
            else
            {
            String xmlcode = getWeatherXML();
            textausgabe.setText(parseXML(xmlcode)); //xml holen & parsen !!!!!!
            }
    }
   public String getWeatherXML() 
   {
       //String cityString = texteingabe.getText().toString(); 
       HttpGet getRequest = new HttpGet(xmlurl); //  + cityString.replace(" ", "%20")   
       try{
           HttpResponse getResponse = httpcli.execute(getRequest);
            final int statusCode = getResponse.getStatusLine().getStatusCode(); //http statusCodes prüfen
           if(statusCode != HttpStatus.SC_OK) { //falls fehlermeldung
              
               return null; 
                   } 
           HttpEntity getResponseEntity = getResponse.getEntity();
           if (getResponseEntity != null) {
               
               return EntityUtils.toString(getResponseEntity); //xml string zurück
                   }
          
       }
       catch(Exception ex) {
           getRequest.abort(); //request abbrechen
           textausgabe.setText("Error loading XML"); 
       } 
       return null; 
       
    }
   private Document stringToDoc(String xmldata) //String in Doc wandeln
   {
       try{
           DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
           DocumentBuilder builder = factory.newDocumentBuilder();
           return builder.parse(new InputSource(new StringReader(xmldata)));
           
       }catch (Exception ex) {
           return null;
       }
   }
   private String parseXML(String xml)
   {
       String expression = "/current/member"; 
       try{
           XPath xpath = XPathFactory.newInstance().newXPath();
           Node xmlnode = (Node) xpath.evaluate(expression, stringToDoc(xml), XPathConstants.NODE);
           return xmlnode.getAttributes().getNamedItem("vorstand").getNodeValue(); 
           
       } catch(Exception ex) {
           return "Error while parsing XML";
 
Dein xpath Ausdruck in der Variable "expression" sucht alle Elemente namens "member", die Kind von einem Element namens "current" sind. Und davon gibt dein code das Attribut "vorstand" aus. Das klingt nicht nach dem was du wirklich suchst. :D
 
Zuletzt bearbeitet:
Doch eigentlich wollte ich das ausgeben. Zumindest wollte ich den Text "David" ausgeben.:unsure:
Der Quelltext einer Seite sieht wie folgt aus:
(habe die Seite nur zum Testen angelegt)

<html>

-<head></head>
-<body>
--<current>
---<member it-verantworlicher="Sevi S." vorstand="David </member>
--<news ticker="WingLA_sucht_neue_Mitglieder"> … </news>

Für
Code:
String [B]expression = "html/body/current/member"[/B];         
try{            XPath xpath = XPathFactory.newInstance().newXPath();            
Node xmlnode = (Node) xpath.evaluate(expression, stringToDoc(xml), XPathConstants.NODE);      
return xmlnode.getAttributes().[B]getNamedItem("vorstand")[/B].getNodeValue();
müsste jetzt doch "David" ausgegeben werden oder?! Leider funktioniert das nicht. Er ließt zwar den Quelltext ein aber das Parsen funktioniert nicht. Auch bei folgender Seite (WIngLA) schaffe ich es nicht mir irgendetwas vom Quelltext auszugeben. Bei anderen Seiten geht das wiederum ohne Probleme.

In den String expression wird doch der Pfad ausgehend von der ersten Ebene der Baumstruktur (meist "html") bis zum gewünschten Element angegeben?! Oder verstehe ich da was falsch?


Danke
 
Zuletzt bearbeitet:
current und member sind keine html Elemente. Also fährt die Seite neben der Spezifikation und damit muss man auf eine Menge gefasst sein. :D

Aber: Einer oder zwei slash am Anfang (/html oder //html) sind nicht verkehrt.
 
XML und vorallem HTML parsen ist sowieso eine Sache für sich :D


Aber hast du mal im Debugger geguckt welches Objekt überhaupt in xmlnode gespeichert wird? und was getAttributes zurück gibt?
 
Der Quelltext wird in jedem Fall in einen String eingelesen.
Der Rest des Codes funktioniert wohl nur wenn es sich um "echte" HTML Attribute handelt. Das war mir nicht klar aber mit dieser Erkenntniss muss ich bestätigen dass es wirklich nicht das war was ich suche...

Ich bräuchte nun einen Code der mir aus einem String eine Zeichenkette an einer definierten Stelle ausliest. Also quasi "lies zeichen ein, von Ausdruck x bis y" o.ä.

Habe hierzu ein bischen gestöbert aber aufgrund meiner kaum vorhandenen JAVA Kenntnisse kann ich zu diesem Thema nur wenig mit den Hilfeseiten anfangen.

Also wenn Jemand zufällig einen entsprechenden Code greifbar hat und mir zur Verfügung stellen würde (oder vielleicht ein gutes Tutorial hierzu kennt), wäre ich unglaublich dankbar! :rolleyes2:

Und Danke für die bisherigen Hinweise!
 
Habe das ganze nun gelöst. Es wird nun eine Textdatei auf einem Server ausgelesen.
Bei Interesse füge ich hier gern den Code ein.

Seltsamerweise funktioniert das Parsen aber nur bis Android 2.3.3?!
Die App startet ohne Probleme und die weiteren Funktionen laufen auch. Es kommt auch kein Absturz der App wenn das Parsen per OnClick Ereigniss ausgelöst wird. Es passiert schlicht nichts.

Der gesamte Code steckt in einer Activity. Bei Recherche bin ich darauf gestoßen dass offenbar ab 4.0 Prozesse, die kurzzeitig keine Usereingaben zulassen geblockt werden. Habe dass zumindest so verstanden.

Hat jemand ähnliche Erfahrung gemacht und hat einen Lösungsansatz?
 
Also ab 4.0 (evtl schon früher) sind Netzwerk anfragen innerhalb von activities nicht mehr zulässig und müssen in einen eigenen thread ausgelagert werden.

Aber wenn man das nicht macht fliegt eigentlich eine Exception.
 
Zurück
Oben Unten