Steht man vor dem Problem Daten aus HTML-Dokumenten zu extrahieren, kommen einem oft als erstes reguläre Ausdrücke in den Sinn. Kore Nordmann hat jedoch bewiesen, dass es nicht möglich ist, HTML mit regulären Ausdrücken zu parsen und empfiehlt stattdessen die DOM-Extension zu nutzen.
Genau diese nutzt die Zend_Dom_Query-Komponente und bietet eine einfache Möglichkeit, auf ein (X)HTML-Dokument zuzugreifen. Neben dem Zugriff über XPath bietet die Komponente aber auch die Möglichkeit über CSS-Selektoren bestimmte Knoten aus einem Dokument zu selektieren (wie man es von vielen Javascript-Frameworks her kennt).
Der Konstruktor erwartet einen (X)HTML- oder XML-String. Abfragen mit CSS-Selektoren werden über die query
-Methode gemacht welche dann ein Zend_Dom_Query_Result
-Objekt zurückliefert.
$dom = new Zend_Dom_Query($html); $result = $dom->query('selector'); // Zend_Dom_Query_Result implements the Countable and Iterator interface $count = count($result); foreach ($result as $node) { // $node instanceof DOMElement } |
#id |
Findet das Element mit dem angegebenen id-Attribut. Zum Beispiel alle Elemente mit der id “foo” (z. B.
|
|||
---|---|---|---|---|
element |
Findet alle Elemente mit dem angegebenen tag-Namen. Zum Beispiel alle
|
|||
.class |
Findet alle Elemente mit der angegebenen Klasse. Zum Beispiel alle Elemente mit der Klasse “foo” (z. B.
|
|||
[attribute] |
Findet alle Elemente mit dem angegebenen Attribut. Dabei werden 3 Arten unterstützt. 1. Findet alle
2. Findet alle
3. Findet alle
|
Selektoren können auch “verkettet” werden um so Abhängigkeiten definieren.
Das folgende Beispiel findet alle a
-Elemente die ein Unterelement eines Elements mit der Klasse “bar”
sind, welches wiederum ein Unterelement eines Elements mit der id “foo” sein muss
(z. B. <div id="foo"><div><div class="bar"><p><a href="#">Link</a></p></div></div></div>
):
$result = $dom->query('#foo .bar a'); |
Mit einem >
können direkte Abhängigkeiten definiert werden.
Das folgende Beispiel findet alle a
-Elemente die ein direktes Kindelement des Elements mit der
id “foo” sind (z. B. <div id="foo"><a href="#">Link</a></div>
):
$result = $dom->query('#foo > a'); |
Zend_Dom_Query ist übrigens auch fest in Zend_Test_PHPUnit_Controller_TestCase integriert und bietet somit CSS Selector Assertions:
<?php class FooControllerTest extends Zend_Test_PHPUnit_Controller_TestCase { public function testIndexContainsLoginForm() { $this->dispatch('/'); $this->assertQuery('#login-form'); } } |