Andreas Frick Andreas Frick - 1 year ago 51
PHP Question

Create SimpleXMLElement Node with Namespace and prevent namespace repeating

For a google sitemap I want to create XML nodes with namespace. How can I prevent simplexml from inserting the namespace on each node.

Structure that I need:


Structure from my code:

<?xml version="1.0" encoding="UTF-8"?>
<urlset xmlns="" xmlns:xhtml="">
<xhtml:link xmlns:xhtml="xhtml" rel="alternate" hreflang="de-CH" href=""></xhtml:link>
<xhtml:link xmlns:xhtml="xhtml" rel="alternate" hreflang="fr-CH" href=""></xhtml:link>

My Code:

$rootNode = new SimpleXMLElement(
'<?xml version="1.0" encoding="utf-8"?>' .
' <urlset xmlns="" xmlns:xhtml=""></urlset>'

$urlNode = $rootNode->addChild('url');
$urlNode->addChild('loc', '');

foreach (['de', 'fr', 'it', 'en'] as $locale) {
if (in_array($locale, ['it', 'en'])) {

$localeNode = $urlNode->addChild(
'' . '/' . $locale,

$localeNode->addAttribute('rel', 'alternate');
$localeNode->addAttribute('hreflang', $locale . '-CH');
$localeNode->addAttribute('href', '' . '/' . $locale);


Answer Source

You need to specify the namespace in the addChild call as the globally unique "namespace identifier" (URI) not the "local prefix". So in this case, you are binding the xhtml prefix as xmlns:xhtml="" so the namespace URI is

$localeNode = $urlNode->addChild(
    '' . '/' . $locale,

The XML library then looks up the already-assigned prefix for this namespace when generating the XML, and gives the desired result.