Jacques Cornat
Jacques Cornat

Reputation: 1642

Append XML to DOMNode in PHP

I would like to append XML to DOMNode element, but I got the error : "Wrong Document Error".

Here is my code :

$dom = new \DOMDocument();
$dom->loadXML($xmlResources->asXml());
$orderNodeList = $dom->getElementsByTagName('order');

foreach ($orderNodeList as $orderNode) {
    $idAddressDelivery = $orderNode->getElementsByTagName('id_address_delivery')->item(0)->nodeValue;
    $xmlToAppend = $this->getSpecificResource('addresses', $idAddressDelivery); //It returns a SimpleXMLElement

    $tmpNode = new \DOMDocument(); //I create a DOMDocument
    $tmpNode->loadXML($xmlToAppend->asXML()); //I fill it with XML

    $orderNode->appendChild($tmpNode); //I want to put the new XML inside the DOMNode, but it throws an error
}

I've searched on the web, but don't know how to make it, could you tell what's wrong please ?

Thank you for your help ^^

Upvotes: 0

Views: 2202

Answers (3)

hakre
hakre

Reputation: 197775

The error message

Wrong Document Error

while operating with DOMDocument in PHP means, that one node is not part of the document you want it to operate with. A simple example of that is, that you have two different XML or HTML documents.

In your specific case the two documents are:

  1. $dom = new \DOMDocument(); (Line 1 in your example)
  2. $tmpNode = new \DOMDocument(); //I create a DOMDocument (Line 9 in your example)

The Solution

A way to make a node from different documents work together is to import nodes into a document first and then operate with them (for example append them).

An Example

Given two documents, blue - docA and red - docB:

$docA = new DomDocument();
$docA->loadXML('<blue/>');

$docB = new DomDocument();
$docB->loadXML('<red/>');

The document element red of docB can be appended to the document element blue of the former docA by importing the node:

$red = $docA->importNode($docB->documentElement, true);
$docA->documentElement->appendChild($red);

This will successfully append it to the first document which can be easily shown:

$docA->formatOutput = true;
$docA->save('php://output');

Which will give this output (Demo):

<?xml version="1.0"?>
<blue>
  <red/>
</blue>

This hopefully shows you on how you can combine as many documents with each other like you want. Take note that you can't import full DOMDocuments into each other, but you can import the document-element which is the root element node of a document.

Further Stackoverflow References

Similar questions have been asked before, this is a selective list of related Q&A material on site:

Upvotes: 1

ThW
ThW

Reputation: 19492

The nodes are in a separate DOM. But you can only append nodes that are part of the same DOM. Here are two possibilities:

Import the nodes you loaded.

$target = new DOMDocument();
$target->loadXml("<one/>");

$source = new DOMDocument();
$source->loadXml("<two/>");

$target->documentElement->appendChild(
  $target->importNode($source->documentElement, TRUE)
);

echo $target->saveXml();

Load the XML into a fragment and append it.

$target = new DOMDocument();
$target->loadXml("<one/>");

$fragment = $target->createDocumentFragment();
$fragment->appendXml("<two/>");

$target->documentElement->appendChild($fragment);

echo $target->saveXml();

Output:

<?xml version="1.0"?>
<one><two/></one>

HINT: You might want to read about DOMXpath::evaluate(). It allows to fetch nodes using expressions. This is a lot more powerful then methods like DOMNode::getElementsByTagName().

Upvotes: 1

Casimir et Hippolyte
Casimir et Hippolyte

Reputation: 89557

You can't append a foreign node to your document. One way to do that is to create a new fragment in the first document with the xml string of the second document:

$fragment = $dom->createDocumentFragment();
$fragment->appendXML(/* put your xml content as a string here*/);

$orderNode->appendChild($fragment);

Upvotes: 0

Related Questions