W3docs

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 — wenn false (der Standard), werden nur Namespaces zurückgegeben, die am Wurzelelement deklariert sind. Bei true wird der gesamte Dokumentbaum durchsucht und auch auf Nachfahren deklarierte Namespaces werden einbezogen.
  • $from_root — wenn true (der Standard), beginnt die Suche ab dem Dokumentstamm, auch wenn die Methode auf einem Unterelement aufgerufen wird. Auf false setzen, 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:

php— editable, runs on the server

Ausgabe:

Prefix: bk, URI: https://example.com/books

Die 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:

MethodeGeltungsbereich
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) oder registerXPathNamespace() 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.

Übung

Übung
Was gibt SimpleXMLElement::getDocNamespaces(true) zurück, was getDocNamespaces() (der Standard) nicht zurückgibt?
Was gibt SimpleXMLElement::getDocNamespaces(true) zurück, was getDocNamespaces() (der Standard) nicht zurückgibt?
Was this page helpful?