This question is intended as a reference to answer a particularly common question, which might take different forms:
A colon (:
) in a tag or attribute name means that the element or attribute is in an XML namespace. Namespaces are a way of combining different XML formats / standards in one document, and keeping track of which names come from which format. The colon, and the part before it, aren't really part of the tag / attribute name, they just indicate which namespace it's in.
An XML namespace has a namespace identifier, which is identified by a URI (a URL or URN). The URI doesn't point at anything, it's just a way for someone to "own" the namespace. For instance, the SOAP standard uses the namespace http://www.w3.org/2003/05/soap-envelope
and an OpenDocument file uses (among others) urn:oasis:names:tc:opendocument:xmlns:meta:1.0
. The example in the question uses the namespaces http://example.com
and https://namespaces.example.org/two
.
Within a document, or a section of a document, a namespace is given a local prefix, which is the part you see before the colon. For instance, in different documents, the SOAP namespace might be given the local prefix soap:
, SOAP:
, SOAP-ENV:
, env:
, or just ns1:
. These names are linked back to the identifier of the namespace using a special xmlns
attribute, e.g. xmlns:soap="http://www.w3.org/2003/05/soap-envelope"
. The choice of prefix in a particular document is completely arbitrary, and could change each time it was generated without changing the meaning.
Finally, there is a default namespace in each document, or section of a document, which is the namespace used for elements with no prefix. It is defined by an xmlns
attribute with no :
, e.g. xmlns="http://www.w3.org/2003/05/soap-envelope"
. In the example above, <list>
is in the default namespace, which is defined as http://example.com
.
Somewhat peculiarly, un-prefixed attributes are never in the default namespace, but in a kind of "void namespace", which the standard doesn't clearly define. See: XML Namespaces and Unprefixed Attributes
If you use print_r
, var_dump
, or similar "dump structure" functions on a SimpleXML object with namespaces in, some of the contents will not display. It is still there, and can be accessed as described below.
SimpleXML provides two main methods for using namespaces:
Both of these methods take the namespace identifier as their first argument. Since these identifiers are rather long, it can be useful to define a constant or variable to represent the namespaces you're working with, so you don't have to copy and paste the full URI everywhere.
For instance, the example above might become:
define('XMLNS_EG2', 'https://namespaces.example.org/two');
define('XMLNS_SEQ', 'urn:example:sequences');
foreach ( $sx->list->children(XMLNS_EG2)->item as $item ) {
echo 'Position: ' . $item->attributes(XMLNS_SEQ)->position . "\n";
echo 'Item: ' . (string)$item . "\n";
}
As a short-hand, you can also pass the methods the local alias of the namespace, by giving the second parameter as true
. Remember that this prefix could change at any time, for instance, a generator might assign prefixes ns1
, ns2
, etc, and assign them in a different order if the code changes slightly. Using this short-hand, the code would become:
foreach ( $sx->list->children('ns2', true)->item as $item ) {
echo 'Position: ' . $item->attributes('seq', true)->position . "\n";
echo 'Item: ' . (string)$item . "\n";
}
(This short-hand was added in PHP 5.2, and you may see really old examples using a more long-winded version using $sx->getNamespaces
to get a list of prefix-identifier pairs. This is the worst of both worlds, as you're still hard-coding the prefix rather than the identifier.)