Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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?

like image 568
waxical Avatar asked Jan 19 '23 06:01

waxical


2 Answers

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());
like image 60
Francois Deschenes Avatar answered Jan 26 '23 00:01

Francois Deschenes


You wrote that you want to remove that. Best way is to not put it in the first place.

This works by prefixing with xmlns: (another time) - it somehow enables a special mode of operation in simplexml - and not providing an empty namespace-URI (otherwise you actually ask for adding that):

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

This creates the following output (beautified for your reading pleasure):

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

This "cheat" was originally hinted in "Unable to add Attribute with Namespace Prefix using PHP Simplexml" but was missing here.

like image 27
hakre Avatar answered Jan 26 '23 00:01

hakre