getDocNamespaces()
SimpleXML ist eine PHP-Erweiterung mit einer einfachen API für XML-Dokumente. Die Methode SimpleXMLElement::getDocNamespaces() gibt deklarierte Namespaces zurück.
Einführung
SimpleXML ist eine PHP-Erweiterung, die eine einfache, objektorientierte API zum Lesen von XML-Dokumenten bietet. XML-Namespaces ermöglichen es, zwei Vokabulare in einem Dokument zu verwenden, ohne dass ihre Elementnamen kollidieren — jeder Namespace wird durch eine URI identifiziert und üblicherweise über ein kurzes Präfix referenziert (z. B. bk in <bk:title>).
SimpleXMLElement::getDocNamespaces() ist die Methode, die angibt, welche Namespaces ein Dokument deklariert. Sie wird typischerweise aufgerufen, bevor man children() oder xpath() auf Daten mit Namespaces anwendet, da man die URIs benötigt, um diese Knoten anzusprechen. Dieses Kapitel behandelt die Syntax, den Unterschied, den das Flag $recursive macht, die Falle mit dem Standard-Namespace und den Unterschied zur ähnlich benannten Methode getNamespaces().
Syntax
public SimpleXMLElement::getDocNamespaces(bool $recursive = false, bool $from_root = true): array$recursive— wennfalse(der Standard), werden nur Namespaces zurückgegeben, die am Wurzelelement deklariert sind. Beitruewird der gesamte Dokumentbaum durchsucht und auch auf Nachfahren deklarierte Namespaces werden einbezogen.$from_root— wenntrue(der Standard), beginnt die Suche ab dem Dokumentstamm, auch wenn die Methode auf einem Unterelement aufgerufen wird. Auffalsesetzen, um nur ab dem aktuellen Knoten zu suchen.
Der Rückgabewert ist ein assoziatives array, das jeden Namespace-Präfix (der string vor dem Doppelpunkt) seiner URI zuordnet.
Einfaches Beispiel
Dieses Dokument deklariert einen Namespace, bk, auf seinem Wurzelelement:
Ausgabe:
Prefix: bk, URI: https://example.com/booksDie Methode gibt ein assoziatives array zurück, sodass ein foreach mit $prefix => $uri alle Deklarationen in einer Schleife durchläuft.
Was $recursive tatsächlich ändert
Das Flag ist nur relevant, wenn ein Namespace unterhalb des Wurzelelements deklariert wird. Hier ist lib am Wurzelelement, aber dc wird auf einem verschachtelten <details>-Element deklariert:
<?php
$xml = new SimpleXMLElement(
'<library xmlns:lib="https://example.com/library">'
. ' <lib:book>'
. ' <details xmlns:dc="https://purl.org/dc/elements/1.1/">'
. ' <dc:title>PHP Basics</dc:title>'
. ' </details>'
. ' </lib:book>'
. '</library>'
);
echo "Root only:\n";
print_r($xml->getDocNamespaces(false));
echo "Whole document:\n";
print_r($xml->getDocNamespaces(true));Ausgabe:
Root only:
Array
(
[lib] => https://example.com/library
)
Whole document:
Array
(
[lib] => https://example.com/library
[dc] => https://purl.org/dc/elements/1.1/
)Übergeben Sie true, wenn Sie nicht garantieren können, dass jeder Namespace am Wurzelelement deklariert ist — Feeds und aggregierte Dokumente deklarieren häufig weitere Namespaces tiefer im Baum.
Die Falle mit dem Standard-Namespace
Ein mit xmlns="..." deklarierter Namespace (ohne Präfix) ist der Standard-Namespace des Dokuments. getDocNamespaces() gibt ihn unter einem leeren string-Schlüssel zurück, nicht unter der URI:
<?php
$xml = new SimpleXMLElement(
'<feed xmlns="http://www.w3.org/2005/Atom" xmlns:media="http://search.yahoo.com/mrss/">'
. '<entry><title>Hello</title></entry>'
. '</feed>'
);
print_r($xml->getDocNamespaces(true));Ausgabe:
Array
(
[] => http://www.w3.org/2005/Atom
[media] => http://search.yahoo.com/mrss/
)Sie benötigen diese URI mit leerem string-Schlüssel, um Knoten im Standard-Namespace zu lesen, z. B. über $xml->children('http://www.w3.org/2005/Atom') oder indem Sie ihn mit registerXPathNamespace() vor einer xpath()-Abfrage registrieren.
getDocNamespaces() vs. getNamespaces()
Diese beiden Methoden sind leicht zu verwechseln:
| Methode | Geltungsbereich |
|---|---|
getDocNamespaces() | Namespaces, die im Dokument deklariert sind (die xmlns-Attribute), unabhängig davon, ob sie verwendet werden. |
getNamespaces() | Namespaces, die tatsächlich vom Element und (optional) seinen Kindern verwendet werden — deklarierte, aber nicht verwendete Namespaces werden ausgeschlossen. |
Kurz gesagt: getDocNamespaces() beantwortet die Frage „Was definiert dieses Dokument?", während getNamespaces() beantwortet: „Was verwendet dieser Teil des Dokuments?".
Wann man sie verwenden sollte
- Vor der Abfrage von Knoten mit Namespaces — die zurückgegebenen URIs in
children($uri)oderregisterXPathNamespace()einspeisen. - Beim Verarbeiten von XML Dritter (RSS/Atom, SOAP, RSS Media, SVG), wenn man die Präfixe nicht kontrolliert.
- Zum Inspizieren oder Validieren der Namespace-Deklarationen eines unbekannten Dokuments.
Fazit
SimpleXMLElement::getDocNamespaces() gibt ein assoziatives array der in einem XML-Dokument deklarierten Namespace-Präfixe und URIs zurück. Verwenden Sie den Standard (false), wenn alle Namespaces am Wurzelelement definiert sind, und übergeben Sie true, um den gesamten Baum zu durchsuchen. Beachten Sie, dass der Standard-Namespace (ohne Präfix) unter einem leeren string-Schlüssel zurückgegeben wird, und greifen Sie auf getNamespaces() zurück, wenn Sie wissen möchten, welche Namespaces tatsächlich verwendet werden, anstatt lediglich deklariert zu sein.