SimpleXMLElement
can only add namespaces indirectly. Since you can only add element and attribute nodes, not namespace declarations, text nodes or other node types, you must somehow make use of SimpleXMLElement->addAttribute()
or SimpleXMLElement->addChild()
. The latter will only add new namespaces to the child, so it's of no use here. addAttribute()
will add the namespace along with an attribute to the given element, so if you then remove the attribute, you're left with the namespace as desired.
There isn't an obvious method of removing an attribute, but the use of unset
as shown in several answers to "Remove a child with a specific attribute, in SimpleXML for PHP" can be adapted to the task, using SimpleXMLElement->attributes()
to get a reference to the attribute.
<?php
$rssXML = new SimpleXMLElement('<rss/>');
$rssXML->addAttribute("version", '2.0');
# add a dummy attribute to get the namespace
$rssXML->addAttribute("media:_", '', "http://search.yahoo.com/mrss/");
unset($rssXML->attributes('media', TRUE)[0]);
# and again
$rssXML->addAttribute("dcterms:_", '', "http://purl.org/dc/terms/");
unset($rssXML->attributes('dcterms', TRUE)[0]);
echo $rssXML->asXML(), "\n";
Result:
<?xml version="1.0"?>
<rss xmlns:media="http://search.yahoo.com/mrss/" xmlns:dcterms="http://purl.org/dc/terms/" version="2.0"/>
The advantage this has over adding the namespace declaration as an attribute with a fake namespace prepended is it's treated as a namespace, rather than an attribute that happens to have something that looks like a namespace prefix in its name.
var_export($rssXML->getDocNamespaces());
Result:
array (
'media' => 'http://search.yahoo.com/mrss/',
'dcterms' => 'http://purl.org/dc/terms/',
)