Unable to add namespace using PHP SimpleXML

I am creating an Atom feed when I tried below to add xmlns:i as an attribute -

 $node->addAttribute("xmlns:i","http://www.w3.org/2001/XMLSchema-instance"); 

I got this as a conclusion -

 i="http://www.w3.org/2001/XMLSchema-instance" 

"xmlns:" part has been disabled. I need to avoid : -character? Or is this any other way to add this namespace?

+7
php simplexml xml-namespaces
source share
3 answers

If you want to add an attribute from the namespace / prefix i to $ node, be sure to declare the namespace in advance. Just use the third addAttribute () parameter to provide the namespace URL for the prefix that you use in the first parameter.

 $node = new SimpleXMLElement('<root></root>'); $node->addAttribute("i:somename", "somevalue", 'http://www.w3.org/2001/XMLSchema-instance'); echo $node->asXml(); 

prints

 <?xml version="1.0"?> <root xmlns:i="http://www.w3.org/2001/XMLSchema-instance" i:somename="somevalue"/> 

If the attribute itself is not needed, you can remove it with unset() , leaving a namespace declaration.

 unset($node->attributes('i', TRUE)['somename']); 
+20
source share

If you do not want to add a dummy element attribute to your root element, you can manually declare the namespace by adding the xmlns attribute for the i prefix:

 <root xmlns:i="http://www.w3.org/2001/XMLSchema-instance"> 

To do this and as hinted at an existing answer ( It is not possible to add an attribute with a namespace prefix using PHP Simplexml ), you must prefix the new attribute with xmlns: (since the xmlns: namespace prefix is ​​not declared in your document). And since xmlns: is part of the name of this attribute, you need two occurrences of xmlns:

 $uri = 'http://www.w3.org/2001/XMLSchema-instance'; $root = new SimpleXMLElement('<root/>'); $root->addAttribute( 'xmlns:xmlns:i', $uri ); ###### $child = $root->addChild('foo'); $child->addAttribute( 'xmlns:i:bar', 'baz'); ###### echo $root->asXml(); 

Gives (formatted manually for reading):

 <?xml version="1.0"?> <root xmlns:i="http://www.w3.org/2001/XMLSchema-instance"> <foo i:bar="baz"/> </root> 

So, the xmlns: prefix seems to fool it. Please note that if you reload the element after setting this attribute, you can use the namespace url also when adding child elements, and this is without prefix:

 $root = new SimpleXMLElement( $root->asXML() ); $child = $root->addChild('foo'); $child->addAttribute( 'i:bar', 'bazy', $uri ); #### echo $root->asXml(); 

Gives (manually formatted again):

 <?xml version="1.0"?> <root xmlns:i="http://www.w3.org/2001/XMLSchema-instance"> <foo i:bar="baz"/> <foo i:bar="bazy"/> </root> 

This second example is apparently closer to the intended (or at least expected) use.

Note that the only way to do this correctly is to use the more complete (but unfortunately more complex and more detailed) DOMDocument classes. This is described in How to declare an XML namespace prefix using DOM / PHP? .

+17
source share

I found this looking for the same thing, and none of the answers actually worked for me. So, I tried a different route. If SimpleXML does not properly manage the namespace, use the DOM instead.

So something like this should work:

 $s = new simplexmlelement('<root/>'); $d = dom_import_simplexml($s); $d->setAttributeNS("http://www.w3.org/2000/xmlns/", "xmlns:i", "http://www.w3.org/2001/XMLSchema-instance"); $s->addChild("bar", "bazy", "http://www.w3.org/2001/XMLSchema-instance"); $f = $s->addChild("foo", "quux"); $f->addAttribute("i:corge", "grault", "http://www.w3.org/2001/XMLSchema-instance"); 

This will result in the following:

 <?xml version="1.0"?> <root xmlns:i="http://www.w3.org/2001/XMLSchema-instance"> <i:bar>bazy</i:bar> <foo i:corge="grault">quux</foo> </root> 
+3
source share

All Articles