XPATH vs DOM

Einklappen
X
 
  • Filter
  • Zeit
  • Anzeigen
Alles löschen
neue Beiträge

  • XPATH vs DOM

    Hallo, bin neu hier und habe mal eine Frage zu XPATH bzw. DOM. Ich wende beides bereits an. Manchmal mit Erfolg, manchmal nicht - also habe ich es noch nicht richtig verstanden. Gibt es eine guten schnellen Weg, die Struktur einer Seite so anzeigen oder ausgeben zu lassen, dass man gleich weiß, wonach man fragen muss, um das Richtige zu bekommen. Also beispielsweise habe ich eine Seite, die so aussieht:

    HTML-Code:
    <div class="img"><a href="http://www.beispiel.de/region.html" title="Beispieltitel" ><img src="http://www.beispielbild.jpg" alt="text" title="beispieltitel" width="236" height="133"/></a></div>
    mit meinem Versuch:
    PHP-Code:
    $doc->loadHTML($data); 
    $xPath = new DOMXPath($doc);
    foreach (
    $xPath->query('//@class="img"') as $element
    echo 
    $element->nodeValue;
    if (
    $zaehler <= 15) {
    $hreft $element->getAttribute('href'); 
    komme ich nicht weiter. Also frage ich offenbar nach dem Falschen. Aber es wäre hilfreich zu wissen, wie man am besten wonach sucht.

    Gruß newbie1955

  • #2
    Guckst du hier - da steht alles schön beschrieben wie man xPath-Abfragen bildet

    http://de.selfhtml.org/xml/darstellung/xpathsyntax.htm

    Für dein Anliegen ist speziell dieser Abschnitt interessant:
    http://de.selfhtml.org/xml/darstellu...on_bedingungen

    Denke aber, dass es dir nicht schadet, die Seite vollständig durchzugehen.
    Zuletzt geändert von Quetschi; 22.12.2012, 23:27.
    Ihr habt ein Torturial durchgearbeitet, das auf den mysql_-Funktionen aufbaut?
    Schön - etwas Geschichte kann ja nicht schaden.
    Aber jetzt seht euch bitte php.net/pdo oder php.net/mysqli bevor ihr beginnt!

    Kommentar


    • #3
      Danke

      erstmal für die Links, habe sie schon mal quergelesen und werde sie auch noch genauer studieren. Was ich noch nicht gefunden habe: Gibt es eine Möglichkeit, sich die Gesamtstruktur eines HTML-Dokuments root-parent-child-usw. ausgeben zu lassen?
      Und dann ist mir noch nicht klar, wann man xpath benutzen sollte und wann nicht.
      Gruß
      newbie1955

      Kommentar


      • #4
        Hallo,

        was verstehst du unter der Gesamtstruktur? Die hast du doch schon in Form des HTML-Quelltextes.

        Zitat von newbie1955 Beitrag anzeigen
        Und dann ist mir noch nicht klar, wann man xpath benutzen sollte und wann nicht.
        Ich nehme es für alles, was per DOM zu umständlich ist. Wenn ich nur das erste Kind eines Elements will, nehme ich firstChild. Wenn ich aber z. B. das erste Kind haben will, welches einen bestimmten Elementtyp hat und entweder das Attribut xyz besitzt oder aber einen nicht-leeren Textinhalt hat, dann codet man sich mit DOM halb tot, während es mit XPath in einer Zeile formuliert ist.

        Amica
        [COLOR="DarkSlateGray"]Hast du die [COLOR="DarkSlateGray"]Grundlagen zur Fehlersuche[/color] gelesen? Hast du Code-Tags benutzt?
        Hast du als URL oder Domain-Beispiele example.com, example.net oder example.org benutzt?
        Super, danke!
        [/COLOR]

        Kommentar


        • #5
          Ich denke er meint die Elementverschachtelung ohne "content" und ggf. auch ohne Elementattribute.
          Ihr habt ein Torturial durchgearbeitet, das auf den mysql_-Funktionen aufbaut?
          Schön - etwas Geschichte kann ja nicht schaden.
          Aber jetzt seht euch bitte php.net/pdo oder php.net/mysqli bevor ihr beginnt!

          Kommentar


          • #6
            Zitat von AmicaNoctis Beitrag anzeigen
            Hallo,

            was verstehst du unter der Gesamtstruktur? Die hast du doch schon in Form des HTML-Quelltextes.



            Ich nehme es für alles, was per DOM zu umständlich ist. Wenn ich nur das erste Kind eines Elements will, nehme ich firstChild. Wenn ich aber z. B. das erste Kind haben will, welches einen bestimmten Elementtyp hat und entweder das Attribut xyz besitzt oder aber einen nicht-leeren Textinhalt hat, dann codet man sich mit DOM halb tot, während es mit XPath in einer Zeile formuliert ist.

            Amica
            Danke für Deine Antwort, auch für die Erklärung, wann Du was nimmst. Es ist genau, wie Quetschi schreibt: Die "nackte" Struktur ohne Inhalt, so in Form eines "Baums" genau für eine bestimmte Seite, abstrakt findet man sowas ja auch in Manuals als Beispiel - meistens anhand z. B. einer Bibliothek mit Autor, Titel usw.). Es müsste doch möglich sein, eine Seite so darstellen zu lassen, dass man auch bei sehr "großen" Seiten auf Anhieb weiß, was ist das FirstChild wovon usw. Das ist ja bei realen (manchmal natürlich auch unsauber geschriebenen) Seiten nicht immer soooo übersichtlich. Im Moment wüsste ich da nur den Weg, mir selber einen "Baum zu malen". Gibt es da was Einfacheres?

            Gruß

            newbie1955
            Zuletzt geändert von newbie1955; 23.12.2012, 20:53.

            Kommentar


            • #7
              Die gängigen Browser bieten entsprechende Funktionalitäten in den Entwicklertools.
              Bei Firefox, Chrome z.B. einfach rechtsklick in die Seite und "Element untersuchen" wählen.
              InternetExplorer -> Taste F12 (funktioniert auch in Chrome).

              Zwar wird hier auch Text-Content angezeigt - dafür kannst du verschachtelte Strukturen ein/ausklappen.
              Ihr habt ein Torturial durchgearbeitet, das auf den mysql_-Funktionen aufbaut?
              Schön - etwas Geschichte kann ja nicht schaden.
              Aber jetzt seht euch bitte php.net/pdo oder php.net/mysqli bevor ihr beginnt!

              Kommentar


              • #8
                Zitat von AmicaNoctis Beitrag anzeigen
                Wenn ich aber z. B. das erste Kind haben will, welches einen bestimmten Elementtyp hat und entweder das Attribut xyz besitzt oder aber einen nicht-leeren Textinhalt hat, dann codet man sich mit DOM halb tot, während es mit XPath in einer Zeile formuliert ist.
                Oder meist auch recht schnell und simpel per CSS3-Selektoren – kann man auch serverseitig nutzen, hiermit: phpquery - phpQuery - jQuery port to PHP - Google Project Hosting
                I don't believe in rebirth. Actually, I never did in my whole lives.

                Kommentar


                • #9
                  Zitat von Quetschi Beitrag anzeigen
                  Die gängigen Browser bieten entsprechende Funktionalitäten in den Entwicklertools.
                  Bei Firefox, Chrome z.B. einfach rechtsklick in die Seite und "Element untersuchen" wählen.
                  InternetExplorer -> Taste F12 (funktioniert auch in Chrome).

                  Zwar wird hier auch Text-Content angezeigt - dafür kannst du verschachtelte Strukturen ein/ausklappen.
                  Ja, F12, war mir zwar bekannt, habe ich aber immer nur zum Untersuchen meiner website bei Fehlern angewendet. Habe jetzt mal die Struktur der einzulesenden Seite untersucht und es mit DOM und xpath versucht, dennoch kommt immer gar nix, was ich nicht verstehe, bei anderen Seiten klappt es.
                  Also der entsprechende Teil der Seite sieht so aus:
                  HTML-Code:
                  <div class="bd">
                  <div class="hl">
                  <a title="Die Hirten kamen als Bauarbeiter" href="http://www.testseite.de/usw.html">Die Hirten kamen als Bauarbeiter</a>
                  </div>
                  Wenn ich jetzt so suche:
                  PHP-Code:
                  $data file_get_contents('http://www.testseite.de/region/');  
                  $doc = new DOMDocument(); 
                  $doc->loadHTML($data); 
                  $result $doc->getElementsByTagName("h1"); 
                  $zaehler 1;
                  foreach (
                  $result as $node
                  $hreft $element->getAttribute('href');
                     echo 
                  "<li><a href=$hreft target='_blank'>" 
                                     
                  $element->nodeValue '</a></li>'
                  müssten doch title und href kommen, oder? Genauso bei:
                  PHP-Code:
                  $data file_get_contents('http://www.testseite.de/region.html');
                    
                  $doc = new DOMDocument(); 
                  $doc->loadHTML($data); 

                  $xPath = new DOMXPath($doc);

                  foreach (
                  $xPath->query('//h1') as $element
                   {

                  if (
                  $zaehler <= 15) {


                  $hreft $element->getAttribute('href');

                           echo 
                  "<li><a href=$hreft target='_blank'>" 
                                     
                  $element->nodeValue '</a></li>'
                  Habe es auch mit
                  PHP-Code:
                  foreach( $xpath->query('//div[contains(attribute::class, "h1")]') as $e ) {
                    echo 
                  $e->nodeValue"<br />\n"
                  versucht.
                  Dennoch kommt bei allen dreien nix. wenn ich dagegen die vorherige Klasse "bd" suche, dann kommt was. Gruß
                  newbie1955
                  Zuletzt geändert von newbie1955; 25.12.2012, 23:33.

                  Kommentar


                  • #10
                    Nächster Versuch:

                    ...ich lasse Euch mal an meinen Versuchen teilhaben, vielleicht habt Ihr dann den entscheidenden Tipp.

                    Die class "h1" bringt partout kein Ergebnis, aber class "bd" schon, und zwar dieses:
                    HTML-Code:
                    Von Glückssymbolen auf Neujahrskarten                                                                                 
                     Wolfenbüttel Die neue Ausstellung von Dietmar Dolle ist bis Mitte Januar 
                    im Schaufenster der Aktionsgemeinschaft Altstadt...                                     
                    danach der nächste Inhalt von "bd" usw. Auf der ausgelesenen website
                    sieht die Struktur so aus:

                    HTML-Code:
                    <div class="g_1of1">  
                    <div id="top" class="mod mod_teaser mod_teaser_nw">    
                    <div class="newsticker_page active">       
                    <div class="mod">         
                    <div class="img">         
                    <div class="bd">               
                        <div class="hl"><a title="Von Glückssymbolen auf Neujahrskarten" 
                    
                    href="http://www.testseite.de/region/wolfenbuettel/von-glueckssymbolen-auf-neujahrskarten-id841165.html">
                    Von Glückssymbolen auf Neujahrskarten</a></div>
                         <div class="txt"><span class="loc">Wolfenbüttel</span><a 
                    title="Von Glückssymbolen auf Neujahrskarten" 
                    href="http://www.testseite.de/region/wolfenbuettel/von-glueckssymbolen-auf-neujahrskarten-id841165.html">
                    Die neue Ausstellung von Dietmar Dolle ist bis Mitte Januar 
                    im Schaufenster der Aktionsgemeinschaft Altstadt...
                    Ich bekomme also offenbar den Inhalt von div "txt" in div "bd". Ich brauche aber nur den Inhalt von "title" und den Link von "href", die ja in "h1" und "txt" gleich sind. Meinen jetzigen Teil-"Erfolg" habe ich mit
                    PHP-Code:
                    foreach( $xpath->query('//div[contains(attribute::class, "bd")]') as $e ) {

                      echo 
                    $e $e->nodeValue"<br />\n"
                    erreicht. Alle versuche, title und href herauszufiltern, scheiterten. Einen Tipp?

                    Gruß
                    newbie1955
                    Zuletzt geändert von newbie1955; 26.12.2012, 20:26.

                    Kommentar


                    • #11
                      Ein div-Tag mit der class 'h1' wirst du nicht über getElementsByTagName('h1') ansprechen können.

                      Du bringst da ein paar grundlegende Definitionen von Html ziemlich durcheinander. Solange du hier nicht sattelfest bist, werden deine Versuche mit xPath zu arbeiten eher ein heiteres Ratespiel bleiben.

                      Du solltest dir daher meiner Ansicht nach die Begriffsdefinitionen von Html noch einmal gründlich einverleiben. Dir an dieser Stelle weiterzuhelfen hat jedenfalls keinen Sinn, weil du morgen mit der nächsten Frage hier ankommen wirst.
                      Ihr habt ein Torturial durchgearbeitet, das auf den mysql_-Funktionen aufbaut?
                      Schön - etwas Geschichte kann ja nicht schaden.
                      Aber jetzt seht euch bitte php.net/pdo oder php.net/mysqli bevor ihr beginnt!

                      Kommentar


                      • #12
                        Zitat von Quetschi Beitrag anzeigen
                        Ein div-Tag mit der class 'h1' wirst du nicht über getElementsByTagName('h1') ansprechen können.

                        Du bringst da ein paar grundlegende Definitionen von Html ziemlich durcheinander. Solange du hier nicht sattelfest bist, werden deine Versuche mit xPath zu arbeiten eher ein heiteres Ratespiel bleiben.

                        Du solltest dir daher meiner Ansicht nach die Begriffsdefinitionen von Html noch einmal gründlich einverleiben. Dir an dieser Stelle weiterzuhelfen hat jedenfalls keinen Sinn, weil du morgen mit der nächsten Frage hier ankommen wirst.
                        naja, sooo ahnungslos bin ich ja auch wieder nicht. Außerdem sah mein letzter Versuch ja so aus:

                        Code:
                        [COLOR=#000000][COLOR=#006600]foreach( [/COLOR][COLOR=#0000CC]$xpath[/COLOR][COLOR=#006600]->[/COLOR][COLOR=#0000CC]query[/COLOR][COLOR=#006600]([/COLOR][COLOR=#CC0000]'//div[contains(attribute::class, "bd")]'[/COLOR][COLOR=#006600]) 
                        as [/COLOR][COLOR=#0000CC]$e [/COLOR][COLOR=#006600]) {[/COLOR][/COLOR]
                        Ich habe mir ein Firefox-Addon geholt (xpathfinder), der mir anzeigt, dass sowohl "bd" als auch "h1" eine class ist, warum ich die eine finde, die andere nicht, verstehe ich halt nicht.

                        Aber ich will gerne zugeben, dass es mir an einigen Basics fehlt, nur den goldenen Weg, mir diese anzueignen, habe ich noch nicht gefunden. Also gerade HTML habe ich mir eigentlich recht umfangreich "reingezogen" (Galileo-Computing-Lehrgänge; selfhtml; manuals und foren). Aber manche Sachen kapiere ich wirklich nicht. Auch in dem hier empfohlenen Link:
                        SELFHTML: XML / Darstellung von XML-Daten / XPath-Syntax

                        hakt es bei mir an vielen Stellen. Den Satz dort
                        Code:
                        Beim Übersetzen einer XML-Dokumentstruktur in eine andere  XML-Dokumentstruktur, also etwa beim Übersetzen eines Dokuments mit  eigener XML-DTD in ein HTML-Dokumen
                        kapiere ich beispielsweise nicht, ich will doch nix in ein HTML-Dokument übersetzen, sondern etwas aus dem HTML herauslesen. Also wenn Ihr da noch mal einen Link für mich habt, bin ich dankbar. Zu meinem Hintergrund: Ich habe mal vor vielen Jahren als COBOL-Programmierer gearbeitet, das war eine andere Welt. Dann 2 1/2 Jahrzehnte nix derartiges gemacht und habe jetzt in den letzten zwei Jahren mich der HTML-Welt angenähert, erst mit webbaukästen und jetzt zuletzt direkt in HTML, CSS und PHP Seiten geschrieben, die ganz gut funktionieren und selbst beim W3-Validator passieren.

                        (Und selbst getElementsByTagName('h1') hat bei anderen Seiten geklappt).

                        Also: für Empfehlungen dankbar, verspreche auch, hier nicht alle 3 Minuten mit neuen Fragen auf der Matte zu stehen.

                        Gruß
                        newbie1955

                        Kommentar


                        • #13
                          xPath kann in Xslt-Stylesheets angewendet werden oder aber auch z.B. in PHP mit der xPath-Klasse. Von daher passt die Doku schon.

                          Mal so a kleines Script zum Verständnis:
                          PHP-Code:
                          <?php


                          $html 
                          '<html>
                          <h1 class="ichBinEinAttribut">
                          <a href="/abc.html">Bla</a>
                          </h1>
                          <div class="h1">
                          <p>Blabla</p>
                          <a href="/xyz.html">Blub</a>
                          </div>
                          </html>'
                          ;

                          $doc = new DOMDocument(); 
                          $doc->loadHTML($html); 

                          $xPath = new DOMXPath($doc);

                          echo 
                          "<h2>Suche mit '//h1' nach h1-Elementen</h2>";
                          $result $xPath->query('//h1');
                          foreach(
                          $result as $element)
                          {
                              echo 
                          "<h3>Mein Tag-Name ist: ".$element->nodeName."</h3>";
                              echo 
                          "<p>Ich enthalte ein Attribut mit dem Namen 'class' das den Wert '".$element->getAttribute("class")."' enthält!</p>";
                              
                              if(!
                          $element->getAttribute("href"))
                              {
                                  echo 
                          "<p>Da ich kein a-Tag bin, habe ich kein Attribut mit dem Namen 'href'!</p>";
                              }
                              
                              echo 
                          "<p>Was sonst noch in mir steckt:<br />".$element->nodeValue."</p>";

                          }


                          echo 
                          "<h2>Suche mit '//div[@class=\"h1\"]' nach div-Elementen mit der Klasse 'h1'</h2>";
                          $result $xPath->query('//div[@class="h1"]');
                          foreach(
                          $result as $element)
                          {
                              echo 
                          "<h3>Mein Tag-Name ist: ".$element->nodeName."</h3>";
                              echo 
                          "<p>Ich enthalte ein Attribut mit dem Namen 'class' das den Wert '".$element->getAttribute("class")."' enthält!</p>";
                              
                              if(!
                          $element->getAttribute("href"))
                              {
                                  echo 
                          "<p>Da ich kein a-Tag bin, habe ich kein Attribut mit dem Namen 'href'!</p>";
                              }
                              
                              echo 
                          "<p>Was sonst noch in mir steckt:<br />".$element->nodeValue."</p>";
                          }


                          echo 
                          "<h2>Suche nach a-Tags '//a' nach a-Elementen</h2>";
                          $result $xPath->query('//a');
                          foreach(
                          $result as $element)
                          {
                              echo 
                          "<h3>Mein Tag-Name ist: ".$element->nodeName."</h3>";
                              echo 
                          "<p>Ich enthalte ein Attribut mit dem Namen 'href' das den Wert '".$element->getAttribute("href")."' enthält!</p>";    
                              echo 
                          "<p>Was sonst noch in mir steckt:<br />".$element->nodeValue."</p>";
                          }

                          ?>
                          Ihr habt ein Torturial durchgearbeitet, das auf den mysql_-Funktionen aufbaut?
                          Schön - etwas Geschichte kann ja nicht schaden.
                          Aber jetzt seht euch bitte php.net/pdo oder php.net/mysqli bevor ihr beginnt!

                          Kommentar


                          • #14
                            Danke

                            ..für das Script. Ich habe es auf den Fall der Testseite angewandt - und verstehe nach wie vor nicht, wieso weder bei Variante a noch bei b unter "h1"
                            ein Ergebnis kommt, während es bei "bd" kommt, obwohl beides div-tags und beides classes sind.

                            HTML-Code:
                            <div class="bd">
                                    <div class="hl">
                                                                <a href="http://www.testseite.de/region/hunde-aus-tierheim-kosten-nur-die-haelfte-id842438.html" title="Hunde aus Tierheim kosten nur die Hälfte" >Hunde aus Tierheim kosten nur die Hälfte</a>
                            Ich muss also nach dem a-tag suchen, der NACH einem h1-Attribut kommt, wenn ich es richtig verstehe (ist dass dann ein firstChild?.) Und dann den href des a und den nodeValue des a-tags.
                            Gruß
                            newbie1955

                            Kommentar


                            • #15
                              Zeig mal deinen Ansatz her.
                              Ihr habt ein Torturial durchgearbeitet, das auf den mysql_-Funktionen aufbaut?
                              Schön - etwas Geschichte kann ja nicht schaden.
                              Aber jetzt seht euch bitte php.net/pdo oder php.net/mysqli bevor ihr beginnt!

                              Kommentar

                              Lädt...
                              X