Search code examples
phpxmlsimplexmldomdocument

Appending child to dom adds a redundant namespace prefix to child


I am trying to append an XML fragment into a base document in php. For instance, the base document could be:

<A></A>

And the fragment is:

<B>
  <C xmlns="http://foo"/>
</B>

I expect the result to be:

<A>
  <B>
    <C xmlns="http://foo"/>
  </B>
</A>

I attempted to do this in 2 different ways:

$dom = new \DOMDocument();
$dom->loadXML("<A></A>");
$childDom = new \DOMDocument();
$childDom->loadXML("<B><C xmlns=\"http://foo\"></C></B>");
$childNode = $dom->importNode($childDom->firstChild, true);
$dom->firstChild->appendChild($childNode);
echo $dom->saveXML();
$dom = new \DOMDocument();
$dom->loadXML("<A></A>");
$fragment = $dom->createDocumentFragment();
$fragment->appendXML("<B><C xmlns=\"https://foo\"></C></B>");
$dom->firstChild->appendChild($fragment->firstChild);
echo $dom->saveXML();

Both of these produce the following result:

<A>
  <B xmlns:default="http://foo">
    <default:C xmlns="http://foo"/>
  </B>
</A>

Is there a way in php to obtain the expected result without the redundant xmlns:default attribute and the added default prefix?


Solution

  • Try it this way:

    $xpath = new DOMXPath($dom);
    $destination = $xpath->query('//A');
    
    $fragment = $dom->createDocumentFragment();
    $fragment->appendXML('
      <B>
        <C xmlns="http://foo"/>
      </B>
    ');
    
    $destination[0]->appendChild($fragment);
    echo $dom->saveXml();
    

    Output should be your expected output.