Search code examples
phpxmlrsssimplexmlxml-namespaces

SimpleXML has declaration of xmlns:xmlns="" - no way to remove


So infuriating, I can hardly talk. I've assembled an RSS feed with SimpleXML and yet - it's using name spaces, which are right now. But, it's constantly trying to declare xmlns:xmlns="" in the root node, when output. Even though I do no such thing.

It starts with

$rssXML->addAttribute("version", '2.0');
$rssXML->addAttribute("xmlns:media", "http://search.yahoo.com/mrss/", '');
$rssXML->addAttribute("xmlns:dcterms", "http://purl.org/dc/terms/", '');

and after this I do:-

header("Content-Type: application/rss+xml");

echo $syndicationXML->asXML();

Yet it outputs :-

<?xml version="1.0"?>
<rss xmlns:xmlns="" version="2.0" xmlns:media="http://search.yahoo.com/mrss/" xmlns:dcterms="http://purl.org/dc/terms/"><channel>...

I do not understand all this namespace declaration. What's going on?


Solution

  • The problem with SimpleXML is that it's addAttribute function adds an attribute, not a namespace and although it seems like it does what you want, it's not meant to be used the way you are using it.

    It's meant to add a value that's part of a particular namespace (specified as the third parameter), not to add the namespace itself. The reason why you end up with xmlns:xmlns is because SimpleXML found that you used the xmlns namespace when specifying the name xmlns:media for instance so it created an empty xmlns:xmlns.

    Here are 2 solutions to your problem:

    1. Specify in the namespaces in the constructor.

    $rssXML = new SimpleXMLElement('<rss xmlns:media="http://search.yahoo.com/mrss/" xmlns:dcterms="http://purl.org/dc/terms/" />');
    $rssXML->addAttribute('version', '2.0');
    

    2. Replace xmlns:xmlns="" using preg_replace

    echo preg_replace('/xmlns:xmlns=""\s?/', '', $rssXML->asXML());