PHP-Scripte PHP-Tutorials PHP-Jobs und vieles mehr

PHP-Scripte PHP-Tutorials PHP-Jobs und vieles mehr (https://www.php-resource.de/forum/)
-   PHP Developer Forum (https://www.php-resource.de/forum/php-developer-forum/)
-   -   XPATH vs DOM (https://www.php-resource.de/forum/php-developer-forum/103633-xpath-vs-dom.html)

newbie1955 20-12-2012 20:33

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

Quetschi 22-12-2012 23:19

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.

newbie1955 23-12-2012 14:10

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

AmicaNoctis 23-12-2012 16:29

Hallo,

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

Zitat:

Zitat von newbie1955 (Beitrag 664277)
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

Quetschi 23-12-2012 16:43

Ich denke er meint die Elementverschachtelung ohne "content" und ggf. auch ohne Elementattribute.

newbie1955 23-12-2012 20:51

Zitat:

Zitat von AmicaNoctis (Beitrag 664281)
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

Quetschi 23-12-2012 23:44

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.

wahsaga 23-12-2012 23:54

Zitat:

Zitat von AmicaNoctis (Beitrag 664281)
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

newbie1955 25-12-2012 22:58

Zitat:

Zitat von Quetschi (Beitrag 664289)
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

newbie1955 26-12-2012 20:18

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

Quetschi 27-12-2012 11:38

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.

newbie1955 27-12-2012 14:20

Zitat:

Zitat von Quetschi (Beitrag 664317)
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:

foreach( $xpath->query('//div[contains(attribute::class, "bd")]')
as
$e ) {

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

Quetschi 27-12-2012 15:25

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

?>


newbie1955 27-12-2012 21:44

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

Quetschi 28-12-2012 13:34

Zeig mal deinen Ansatz her.


Alle Zeitangaben in WEZ +2. Es ist jetzt 07:49 Uhr.

Powered by vBulletin® Version 3.8.2 (Deutsch)
Copyright ©2000 - 2020, Jelsoft Enterprises Ltd.
Search Engine Friendly URLs by vBSEO 3.3.0
[c] ebiz-consult GmbH & Co. KG