If you don’t want to have to add a dummy attribute to your root element, you can declare the namespace manually on it by adding an xmlns
attribute for your i
prefix:
<root xmlns:i="http://www.w3.org/2001/XMLSchema-instance">
In order to do so, and as hinted in an existing answer (Unable to add Attribute with Namespace Prefix using PHP Simplexml), you have to prefix the new attribute with xmlns:
(since the xmlns:
namespace prefic is not declared in your document). And since xmlns:
is part of the name of that attribute, you therfore 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 readability):
<?xml version="1.0"?>
<root xmlns:i="http://www.w3.org/2001/XMLSchema-instance">
<foo i:bar="baz"/>
</root>
So this xmlns:
prefixing seems to cheat it. Note that if you reload the element after setting that attribute, it is possible to use the namespace uri as well when adding children, and this without specifying the prefix:
$root = new SimpleXMLElement( $root->asXML() );
$child = $root->addChild('foo');
$child->addAttribute( 'i:bar', 'bazy', $uri );
####
echo $root->asXml();
Gives (again, formatted manually):
<?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 seems to be closer to the intended (or at least expected) use.
Note that the only way to do this properly would be to use the more complete (but unfortunately also more complex and more verbose) DOMDocument classes. This is outlined in How to declare an XML namespace prefix with DOM/PHP?.