W3docs

getDocNamespaces()

SimpleXML is a PHP extension that provides a simple and easy-to-use API for working with XML documents. The SimpleXMLElement::getDocNamespaces() function is one

Introduction

SimpleXML is a PHP extension that provides a simple, object-oriented API for reading XML documents. XML namespaces let two vocabularies share one document without their element names colliding — each namespace is identified by a URI and usually referenced through a short prefix (for example, bk in <bk:title>).

SimpleXMLElement::getDocNamespaces() is the method that tells you which namespaces a document declares. You typically reach for it before calling children() or xpath() on namespaced data, because you need the URIs in order to address those nodes. This chapter covers the syntax, the difference the $recursive flag makes, the default-namespace gotcha, and how it differs from the closely-named getNamespaces().

Syntax

public SimpleXMLElement::getDocNamespaces(bool $recursive = false, bool $from_root = true): array
  • $recursive — when false (the default), only namespaces declared on the root element are returned. When true, the whole document tree is scanned and namespaces declared on any descendant are included too.
  • $from_root — when true (the default), the scan starts from the document root even if you call the method on a sub-element. Set it to false to scan only from the current node down.

The return value is an associative array mapping each namespace prefix (the string before the colon) to its URI.

Basic example

This document declares one namespace, bk, on its root element:

php— editable, runs on the server

Output:

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

The method returns an associative array, so a foreach with $prefix => $uri walks every declaration in one loop.

What $recursive actually changes

The flag only matters when a namespace is declared below the root. Here lib is on the root but dc is declared on a nested <details> element:

<?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));

Output:

Root only:
Array
(
    [lib] => https://example.com/library
)
Whole document:
Array
(
    [lib] => https://example.com/library
    [dc] => https://purl.org/dc/elements/1.1/
)

Pass true whenever you cannot guarantee that every namespace is declared on the root — feeds and aggregated documents often declare extras deeper in the tree.

The default-namespace gotcha

A namespace declared with xmlns="..." (no prefix) is the document's default namespace. getDocNamespaces() returns it under an empty-string key, not under the 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));

Output:

Array
(
    [] => http://www.w3.org/2005/Atom
    [media] => http://search.yahoo.com/mrss/
)

You will need that empty-string URI to read default-namespaced nodes, e.g. $xml->children('http://www.w3.org/2005/Atom') or by registering it with registerXPathNamespace() before an xpath() query.

getDocNamespaces() vs getNamespaces()

These two are easy to confuse:

MethodScope
getDocNamespaces()Namespaces declared in the document (the xmlns attributes), regardless of whether anything uses them.
getNamespaces()Namespaces actually used by the element and (optionally) its children — declared-but-unused namespaces are excluded.

In short: getDocNamespaces() answers "what does this document define?" while getNamespaces() answers "what does this part of the document use?".

When to use it

  • Before querying namespaced nodes — feed the returned URIs into children($uri) or registerXPathNamespace().
  • When consuming third-party XML (RSS/Atom, SOAP, RSS Media, SVG) where you do not control the prefixes.
  • For inspecting or validating an unfamiliar document's namespace declarations.

Conclusion

SimpleXMLElement::getDocNamespaces() returns an associative array of the namespace prefixes and URIs declared in an XML document. Use the default (false) when every namespace lives on the root, and pass true to scan the whole tree. Remember that the default (unprefixed) namespace comes back under an empty-string key, and reach for getNamespaces() instead when you care about which namespaces are actually used rather than merely declared.

Practice

Practice
What does SimpleXMLElement::getDocNamespaces(true) return that getDocNamespaces() (the default) does not?
What does SimpleXMLElement::getDocNamespaces(true) return that getDocNamespaces() (the default) does not?
Was this page helpful?