PHP/Tutorials/DOMDocument

Aus SELFHTML-Wiki
< PHP‎ | Tutorials
Wechseln zu: Navigation, Suche

Die DOM-Klassensammlung in PHP für das Document Object Model (DOM) stellt einen vollständigen Parser für HTML- und XML-Elemente zur Verfügung. Mit Hilfe ihrer Methoden kann man Elemente und Teilbäume aus dem Elementenbaum extrahieren, kopieren, manipulieren und auch in ihn einfügen. So ist es ist z.B. mit wenigen Zeilen möglich, alle Hyperlinks eines Dokumente auszulesen, alle Source-Referenzen auf Bilder auszulesen oder einen kompletten Bereich (=>Fragment, z.B. DIV mit Unterelementen) aus einem Dokument zu extrahieren und in ein anderes wieder einzufügen.

Sinn und Zweck[Bearbeiten]

Wenn man mit HTML-Code auf der Basis von Stringfunktionen hantiert, muss man immer wieder darauf achten, dass die Daten kontextgerecht kodiert werden und dass öffnende und schließende Tags zusammenpassen. Diese Sorgen hat man nicht, wenn man mit dem DOM ein Datenmodell hat, das am Ende korrekt zu HTML-Code serialisiert an den Browser geht.

Beispiel: Hantieren mit Strings
$html = '<h1>' . 'Warum 2 < als 1 ist' . '<h1>';
echo $html;
Dieses Beispiel produziert gleich zwei Fehler: Erstens muss das kleiner-als-Zeichen als HTML-Entität (&lt;) notiert werden und zweitens ist das schließende h1-Tag kein schließendes, sondern erneut ein öffnendes (korrekt wäre </h1> gewesen).

Verwendung[Bearbeiten]

Die diversen DOM-Klassen in PHP folgen dem DOM-Standard und entsprechen damit weitestgehend den Möglichkeiten, die auch z.B. JavaScript im Browser bietet. Daher leistet die DOMDocument-Klasse ähnliches wie der Browser, wenn er ein HTML-Dokument parst.

Laden eines HTML-Dokuments[Bearbeiten]

Beispiel: Öffnen und Auslesen von HTML-Dokumenten
$dom = new DOMDocument;
$dom->loadHTMLFile( 'index.html' );
echo $dom->saveHTML();

// kürzer:
$dom2 = DOMDocument::loadHTMLFile( 'index.html' );
echo $dom2->saveHTML();

In der ersten Anweisung wird eine Instanz der Klasse DOMDocument erzeugt. Dann wird mittels loadHTMLFile() der Inhalt der Datei index.html geladen und geparst. Ab jetzt hat $dom ein HTML-Dokument in seiner Datenstruktur.

Anschließend wird die Datenstruktur mit saveHTML() wieder zu einem String mit HTML-Code serialisiert und per echo an den Browser ausgegeben.

DOM-Methoden[Bearbeiten]

Die Datenstruktur in einem DOMDocument können Sie gemäß des DOM-Standards mit DOM-Methoden nutzen:

Diese beiden Methoden seien nur beispielhaft aufgeführt. Die so erhaltenen Element-Knoten sind wiederum Objekte, aber nicht vom Typ DOMDocument, sondern DOMElement, womit sie wieder andere Möglichkeiten gemäß des DOM-Standards bieten:

Das DOM traversieren und Elemente finden[Bearbeiten]

Es gibt verschiedene Möglichkeiten sich durch das DOM zu bewegen, um Elemente zu finden. Die Funktion getElementsByTagName() z.B. sucht alle Elemente, die den übergebenen Namen besitzen:

Beispiel: alle Textabsätze finden
$Dom = DOMDocument::loadHTMLFile( 'index.html' );
$DomNodeList = $Dom->getElementsByTagName( 'p' );

Rückgabewert ist eine DOMNodeList-Klasse, über die Sie dann mit foreach iterieren und so auf jedes einzelne Element zugreifen können:

Beispiel: Alle Links finden
$xml = '<nav>
  <ul>
    <li><a href="link_1.html">Wiki</a></li>
    <li><a href="link_2.html">Blog</a></li>
    <li><a href="link_3.html">Forum</a></li>
  </ul>
</nav>';

$dom = DOMDocument::loadXML($xml);
$links = $dom->getElementsByTagName('a');

foreach ($links as $book) {
    echo $book->nodeValue, PHP_EOL;
}
Die echo-Anweisungen ergeben diese Ausgabe:
Wiki
Blog
Forum

Die Browser-Hersteller haben die Entwicklungen im Bereich JavaScript mitgetragen und den erweiterten Bedarf an DOM-Methoden umgesetzt, so dass es nun in JavaScript Dinge wie getElementsByClassName gibt, die über den eigentlichen DOM-Standard hinausgehen. Insbesondere das sehr nützliche querySelector, welches CSS-Selektoren versteht und so passende Elemente im Dokument findet, ist in den DOM-Klassen von PHP nicht verfügbar und wird es auch nie sein. Dafür aber gibt es die DOMXPath-Klasse, mit der man etwas ähnliches erreichen kann:

DOMXPath[Bearbeiten]

Die XML Path Language (XPath) dient dem Adressieren von Knoten in XML-Dokumenten (und so auch HTML-Dokumenten) und benutzt hierzu Pfaden ähnliche Ausdrücke. Die PHP DOMXPath-Klasse benutzt jedoch eine andere Notation.

Beispiel: Überprüfung auf vorhandene Verweise
$html = '<!DOCTYPE html><html>
<head><meta cahrset="utf-8"><title>test</title></head>
<body>
  <div>test1</div>
  <div>test2</div>
  <div class="blog">
    test3
    <a href="1">a1-test3</a>
    <p><a href="2">a2-test3</a></p>
  </div>
  <div>test4</div>
  <div class="blog">
    test5
    <a href="3">a1-test5</a>
    <a href="4">a2-test5</a>
  </div>
  <div>test2</div>
  <div>test2</div>
</body></html>
';

$doc = DOMDocument::loadHTML($html);
$xpath = new DOMXpath($doc);

// alle <a href="..."> innerhalb von <div class="blog">
// CSS-Selektor: div.blog a[href]
// z.B. JavaScript: document.querySelector('div.blog a[href]')
$links = $xpath->query('//div[@class="blog"]//a[@href]');

foreach ($links as $a) {
  echo $a->getAttribute('href'),' - ',$a->textContent,PHP_EOL;
}
Die echo-Anweisung in der Schleife führt zu diesem Ergebnis:
1 - a1-test3
2 - a2-test3
3 - a1-test5
4 - a2-test5

Weblinks[Bearbeiten]