XPath ist ja eine ganz tolle Sache, wenn es doch mal auch funktionieren würde wie man es sich so wünscht. Für die tägliche Arbeit ist XPath zum Teil aber mehr Frust als Vergnügen, denn oftmals funktioniert XPath anscheinend nicht. Im folgenden Beispiel möchte ich mir zum Beispiel alle Superhelden anzeigen lassen.
superhelden.xml
Batman
Der dunkler Ritter
Hat keine Superfähigkeiten
batman.jpg
Superman
Kommt von Krypton und hat zu enge Strümpfe an
Laseraugen, Superkraft...
superman.png
Hulk
Grünes Monster mit lila Shorts
Ist wahnsinnig stark wenn es wütend wird. Arghhhh
incredible-hulk.jpg
$xml = “superhelden.xml”;
// gib mir alle helden
$heroes = $xml->xpath(’//helden’);
In diesen Fall bekomme ich nun alle Helden ausgegeben. Doch wo ist nun das Problem? Nehmen wir mal an, die Helden gehören zu einer bestimmten Fraktion, sagen wir mal hier den Guten, so könnte man das natürlich jedem Helden explizit zuteilen. Da wir aber nun wissen dass sowohl Batman, Superman als auch Hulk gut sind, deklarieren wir das doch ganz einfach an den Anfang des XML-Dokumentes.
So, unsere Superhelden sind auch schon im Web 2.0 angekommen und haben sich eine tolle Domain gesichert. Da diese auch tolle Praktikanten im SEO haben, nennen wir diesen Namespace einfach mal superhelden.com/fraktion/gut.
Schaut dann folgendermaßen aus:
superhelden_gut.xml
Batman
Der dunkler Ritter
Hat keine Superfähigkeiten
batman.jpg
Superman
Kommt von Krypton und hat zu enge Strümpfe an
Laseraugen, Superkraft...
superman.png
Hulk
Grünes Monster mit lila Shorts
Ist wahnsinnig stark wenn es wütend wird. Arghhhh
incredible-hulk.jpg
So nun führen wir mal das PHP Skript nochmal aus. Ich kann jetzt schon behaupten, dass nichts zurückkommen wird. Das liegt daran, dass XPath versucht, alle Helden zurückzugeben, die keinen Namespace zugeordnet sind. Blödes XPath, was wäre denn, wenn Commissioner Gordon versuchen würde, Batman aus der Liste zu extrahieren, XPath das aber nicht weil es den vorgegebenen Namespace nicht erkennt? Ganz richtig, alles im Arsch. Auch das Skript.
$xml = “superhelden.xml”;
// gib mir alle helden
$heroes = $xml->xpath(’//helden’);
Die Lösung ist ganz einfach und nennt sich Namespace-Prefix Mapping. Auf gut deutsch übersetzt bedeutet das, dass der Namespace mit PHP registriert werden muss. XPath muss also erfahren, in welchen Namespace es nach den Helden zu suchen hat.
$xml = “superhelden.xml”;
// namespace zum debuggen ausgeben
$namespaces = $this->_xml->getNamespaces(true);
// gibt aus: array([0] => ‘www.superhelden.com/fraktion/gut’)
// namespace registrieren
$xml->registerXPathNamespace(“gut”, $namespaces['www.superhelden.com/fraktion/gut']);
// gib mir alle helden im namespace gut
$heroes = $xml->xpath(’//gut:helden’);
So, das wars auch. Eventuell hilft das ja jemanden weiter. Ich hab wirklich lange gebraucht um darauf zu kommen, dass XPath zu blöd dafür ist.