0

I am trying to use PHP to create an XML document that will be used for an RSS feed. I've got it working for the most part, but I am getting a error on line 2 at column 29: redefinition of the xmlns prefix is forbidden while attempting to add an attribute with a namespace to my document.

I've tried the accepted answer here: Add rss xmlns namespace definition to a php simplexml document? but that changes the first line to <rss... instead of <xml...

Here is the code that I am working with:

<?php
$xml = new SimpleXMLElement('<xml vesion="1.0" />');
$rss = $xml->addChild('rss');
$rss->addAttribute('version','2.0');
$rss->addAttribute("xml:base",'http://intranet/bapm/rss-avd','xml');
$rss->addAttribute('xmlns:dc',"http://purl.org/dc/elements/1.1/",'xmlns');
....

the line that adds the xml:base attribute works fine, but when I add the line that adds the xmlns:dc attribute I get the error. If I don't add the 'xmlns' as the third argument, I get no errors, but the rendered attribute omits the namespace?

Community
  • 1
  • 1
eidsonator
  • 1,319
  • 2
  • 11
  • 25
  • Please double-check, the XML you provide *is invalid*: https://eval.in/33360 - elements starting with the three letters `XML` are reserved in XML. don't use them. (and you likely do not want to create such a root element here) - So please trouble-shoot a bit before posting a question. – hakre Jun 11 '13 at 13:38
  • The same rule for the element names *also* applies to attribute-names btw, `$rss->addAttribute('xmlns:dc', ...` ***can never work*** because that is an invalid attribute. Like with the root element, it is very likely that you want to do something different here, for example adding a *Namespace Declaration* which might look in your eyes like an attribute - but it ain't one (yes keep that in mind, it's not an attribute, it looks like one, but it's not an attribute). – hakre Jun 11 '13 at 13:42
  • Additionally what you write in your question is wrong: You did not try the accepted answer there, it's different to what you do here, fix that difference and you should be fine. – hakre Jun 11 '13 at 13:44
  • I DID try the accepted answer there, and I DID troubleshoot before I posted here, but thanks for the snark, it helped out greatly. – eidsonator Jun 11 '13 at 13:48
  • Yes, but please try to understand why things don't work. The error message is only a hint, the understanding you need to develop because the linked answer *does* solve the issue. I also left you an answer (and edited it right now with further resources) that hopefully give you enough help at hand to handle your issue. – hakre Jun 11 '13 at 14:10

2 Answers2

1

The error message:

redefinition of the xmlns prefix is forbidden

is because xmlns is defined in XML (all names starting with the letters XML regardless of case are reserved), so you can not use "xmlns" as prefix. However in your code you use it as prefix:

$rss->addAttribute('xmlns:dc', "http://purl.org/dc/elements/1.1/", 'xmlns');
                    #####                                           #####

It is just not possible to add such attributes. Remove that line of code and the error goes away. Add the namespace declaration to the string when you create the new object, as shown in the accepted answer to "Add rss xmlns namespace definition to a php simplexml document?".

To make this chrystal clear: You can not use SimpleXMLElement::addAttribute() to make an XML namespace declaration.


Edit: SimpleXML was originally not designed to handle XML Namespaces and not all functionality is easily accessible (or straight-forward). The probably most clean way is using the sister library DOMDocument ("DOM").

For a more detailed review how to add Namespace Declarations in SimpleXML please see the following existing Q&A material here on the Stackoverflow site:

Community
  • 1
  • 1
hakre
  • 193,403
  • 52
  • 435
  • 836
0

Though the XML may not be 'properly' formed - I ran into a similar issue with parsing XML from an external API, and had to make my parser conform to the poorly formed XML.

I was able to add the appropriate namespace (which in my case was another instance of 'redefining' xmlns - and was getting PHP Warnings about being unable to 'redefine' xmlns). I was receiving the above warnings using the three argument syntax as you had before.

If you preface the xmlns namespace with another xmlns the xmlns attribute is added without throwing an exception.

So you'd want to do something like below:

<?php
$xml = new SimpleXMLElement('<xml vesion="1.0" />');
$rss = $xml->addChild('rss');
$rss->addAttribute('version','2.0');
$rss->addAttribute("xml:base",'http://intranet/bapm/rss-avd','xml');
$rss->addAttribute('xmlns:xmlns:dc',"http://purl.org/dc/elements/1.1/");
....

Again note the 'xmlns:xmlns:dc' in the first argument. I cannot speak to the validity of the XML but it allows me to get around the warnings in a quick and functional manner.

josh.chavanne
  • 329
  • 3
  • 11