DOMDocument with namespace
I've been working for a couple of hours trying to get the output XML to match the spec I was given and I just can't seem to find the correct code to do this. I am using DOMDocument because I read that it is more flexible than SimpleXML.
Desired end result:
<?xml version="1.0" encoding="UTF-8"?>
<retail xmlns:i="http://www.w3.org/2001/XMLSchema-instance">
<partnerid>XYZ</partnerid>
<customer xmlns:a="http://schemas.datacontract.org/2004/07/DealerTrack.DataContracts.CreditApp">
<a:info>
<a:FirstName>Bob</a:FirstName>
<a:LastName>Hoskins</a:LastName>
</a:info>
</customer>
<refnum i:nil="true"/>
</retail>
... and the code I'm using to get there (shorthand):
$node = new DOMDocument('1.0', 'UTF-8');
$root = $node->createElementNS( 'http://www.w3.org/2001/XMLSchema-instance', 'retail' );
$root->setAttributeNS('http://www.w3.org/2001/XMLSchema-instance', 'xmlns:i', 'test');
$capp = $node->appendChild($root);
$cnode = $node->createElement("partnerid", 'XYZ');
$capp->appendChild($cnode);
... that doesn't get me what I want. I've tried at least a dozen combinations of createElementNS, setAttributeNS, looked at a few examples and couldn't find anything that brings me closer to what I need. I can already do this in SimpleXML, but I would like to understand what is going on and how to use the DOM in this instance.
source to share
In addition to alex blex's answer: for the root element (and only for it), you can also just create an attribute namespace without adding it to the root element.
$dom = new DOMDocument('1.0', 'UTF-8');
$namespaceURIs = [
'xmlns' => 'http://www.w3.org/2000/xmlns/',
'i' => 'http://www.w3.org/2001/XMLSchema-instance',
'a' => 'http://schemas.datacontract.org/2004/07/DealerTrack.DataContracts.CreditApp'
];
$root = $dom->createElement('retail');
$dom->appendChild($root);
$dom->createAttributeNS($namespaceURIs['i'], 'i:attr');
// note that you don't have to append it: `CreateAttributeNS` defines a namespace for
// the entire document and will be automatically attached to the root element.
$root->appendChild($dom->createElement('partnerid', 'XYZ'));
$customer = $dom->createElement('customer');
$customer->setAttributeNS($namespaceURIs['xmlns'], 'xmlns:a', $namespaceURIs['a']);
// `setAttributeNS` allows to define local namespaces, that why it needs to be
// attached to a particular element.
$root->appendChild($customer);
$info = $dom->createElementNS($namespaceURIs['a'], 'a:info');
$customer->appendChild($info);
// etc.
$dom->preserveWhiteSpace = false;
$dom->formatOutput = true;
echo $dom->saveXML();
Also, feel free to test another php XML build-in api: XMLWriter
source to share
If I understand that the problem is with the element retail
.
$node = new DOMDocument('1.0', 'UTF-8');
$root = $node->createElement('retail' );
$root->setAttributeNS(
'http://www.w3.org/2000/xmlns/',
'xmlns:i',
'http://www.w3.org/2001/XMLSchema-instance'
);
$capp = $node->appendChild($root);
$cnode = $node->createElement("partnerid", 'XYZ');
$capp->appendChild($cnode);
should give you the expected result. It's well documented at http://php.net/manual/en/domdocument.createelementns.php
source to share