The code I have:
$xmlns = [
'xmlns' => 'http://www.w3.org/2000/xmlns/',
'rsm' => 'urn:un:unece:uncefact:data:standard:CrossIndustryInvoice:100',
'ram' => 'urn:un:unece:uncefact:data:standard:ReusableAggregateBusinessInformationEntity:100',
'qdt' => 'urn:un:unece:uncefact:data:Standard:QualifiedDataType:100',
'udt' => 'urn:un:unece:uncefact:data:standard:UnqualifiedDataType:100',
'xsi' => 'http://www.w3.org/2001/XMLSchema-instance',
];
$document = new DOMDocument();
$root = $document->createElementNS($xmlns['rsm'], 'rsm:CrossIndustryInvoice');
$root->setAttributeNS($xmlns['xmlns'], 'xmlns:ram', $xmlns['ram']);
$root->setAttributeNS($xmlns['xmlns'], 'xmlns:qdt', $xmlns['qdt']);
$root->setAttributeNS($xmlns['xmlns'], 'xmlns:udt', $xmlns['udt']);
$root->setAttributeNS($xmlns['xmlns'], 'xmlns:xsi', $xmlns['xsi']);
$document->appendChild($root);
$parent = $document->createElementNS($xmlns['rsm'], 'ExchangedDocumentContext');
$sub = $document->createElementNS($xmlns['ram'], 'GuidelineSpecifiedDocumentContextParameter');
$child = $document->createElementNS($xmlns['ram'], 'ID', 'urn:cen.eu:en16931:2017');
$sub->appendChild($child);
$parent->appendChild($sub);
$root->appendChild($parent);
$parent = $document->createElementNS($xmlns['rsm'], 'ExchangedDocument');
$child = $document->createElementNS($xmlns['ram'], 'ID', 'LoremIpsum');
$parent->appendChild($child);
$root->appendChild($parent);
return $document->saveXML();
The result I get:
<?xml version="1.0"?>
<rsm:CrossIndustryInvoice xmlns:rsm="urn:un:unece:uncefact:data:standard:CrossIndustryInvoice:100" xmlns:ram="urn:un:unece:uncefact:data:standard:ReusableAggregateBusinessInformationEntity:100" xmlns:qdt="urn:un:unece:uncefact:data:Standard:QualifiedDataType:100" xmlns:udt="urn:un:unece:uncefact:data:standard:UnqualifiedDataType:100" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<rsm:ExchangedDocumentContext>
<ram:GuidelineSpecifiedDocumentContextParameter xmlns="urn:un:unece:uncefact:data:standard:ReusableAggregateBusinessInformationEntity:100">
<ram:ID>urn:cen.eu:en16931:2017</ram:ID>
</ram:GuidelineSpecifiedDocumentContextParameter>
</rsm:ExchangedDocumentContext>
<rsm:ExchangedDocument>
<ram:ID xmlns="urn:un:unece:uncefact:data:standard:ReusableAggregateBusinessInformationEntity:100">LoremIpsum</ram:ID>
</rsm:ExchangedDocument>
</rsm:CrossIndustryInvoice>
The result I expect:
<?xml version="1.0"?>
<rsm:CrossIndustryInvoice xmlns:rsm="urn:un:unece:uncefact:data:standard:CrossIndustryInvoice:100" xmlns:ram="urn:un:unece:uncefact:data:standard:ReusableAggregateBusinessInformationEntity:100" xmlns:qdt="urn:un:unece:uncefact:data:Standard:QualifiedDataType:100" xmlns:udt="urn:un:unece:uncefact:data:standard:UnqualifiedDataType:100" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<rsm:ExchangedDocumentContext>
<ram:GuidelineSpecifiedDocumentContextParameter>
<ram:ID>urn:cen.eu:en16931:2017</ram:ID>
</ram:GuidelineSpecifiedDocumentContextParameter>
</rsm:ExchangedDocumentContext>
<rsm:ExchangedDocument>
<ram:ID>LoremIpsum</ram:ID>
</rsm:ExchangedDocument>
</rsm:CrossIndustryInvoice>
Why are there these additional definition of XML namespaces in the child elements? I know, that I can use createElement('ram:GuidelineSpecifiedDocumentContextParameter');
instead of createElementNS($xmlns['ram'], 'GuidelineSpecifiedDocumentContextParameter');
, but that doesn’t feel good or right.
How to do this correctly but still get rid of these namespace re-declarations?
3
My mistake. The cause lies in the order in which the elements are inserted into the XML. When changing the existing code:
$parent = $document->createElementNS($xmlns['rsm'], 'ExchangedDocumentContext');
$sub = $document->createElementNS($xmlns['ram'], 'GuidelineSpecifiedDocumentContextParameter');
$child = $document->createElementNS($xmlns['ram'], 'ID', 'urn:cen.eu:en16931:2017');
$sub->appendChild($child);
$parent->appendChild($sub);
$root->appendChild($parent);
to:
$parent = $document->createElementNS($xmlns['rsm'], 'ExchangedDocumentContext');
$root->appendChild($parent);
$sub = $document->createElementNS($xmlns['ram'], 'GuidelineSpecifiedDocumentContextParameter');
$parent->appendChild($sub);
$child = $document->createElementNS($xmlns['ram'], 'ID', 'urn:cen.eu:en16931:2017');
$sub->appendChild($child);
I get exactly what I want. Notice the change: Instead of preparing whole node tree and appending it to root at least, I append newly created elements immediately to DOM tree.
1