0

I'm really frustrated now since I do not seem to understand why it is that difficult to copy a node (with all the childs) from one XML tree to another.

I googled alot and it seems that I have to read the trees in with SimpleXML and then parse the nodes to DOM to import/export them somehow. Should there be a function doing this in one rush?

Basically I want to copy from the source all processList->process entries to destination test->processList-> .

source:
<processList>
    <process ...>
        //some more child nodes
    </process>
</processList>

destination:
<test>
    <processList>
        <process ...>
            //some more child nodes
        </process>
    </processList>
</test>

Can someone please advise?

1

1 Answer 1

2

DOM can do this easily. DOMDocument::importNode() allows to import a node from another document. The imported node can be appended/inserted like any node.

DOMXpath::evaluate() can be used to fetch the nodes from a DOM.

$sourceXml = <<<'XML'
<processList>
  <process from="source">
    //some more child nodes
  </process>
</processList>
XML;    
$targetXml = <<<'XML'
<test>
  <processList>
    <process from="target">
      //some more child nodes
    </process>
  </processList>
</test>
XML;

$source = new DOMDocument();
$source->loadXml($sourceXml);
$sourceXpath = new DOMXPath($source);

$target = new DOMDocument();
$target->preserveWhiteSpace = false;
$target->formatOutput = true;
$target->loadXml($targetXml);
$targetXpath = new DOMXPath($target);

$targetNode = $targetXpath->evaluate('//processList[1]')->item(0);    
foreach ($sourceXpath->evaluate('//process') as $process) {
  $targetNode->appendChild(
    // import the node into the target document
    $target->importNode($process, TRUE)
  );
}    
echo $target->saveXml();

Output:

<?xml version="1.0"?>
<test>
  <processList>
    <process from="target">
      //some more child nodes
    </process>
    <process from="source">
    //some more child nodes
  </process>
  </processList>
</test>
Sign up to request clarification or add additional context in comments.

4 Comments

Thanks for the answer! However I still dont see a reference. Destination should not be the output in this case. So what i wanted to achieve is to copy the process entries from source NEXT to the process entries of destination. In otherwords, I have both trees read in as SimpleXML and want to copy process nodes from SOURCE to DESTINATION
SimpleXML is an abstraction on top of the DOM, it has no nodes and no document - only SimpleXMLElement objects. This means that it is rather limited and can not copy nodes between documents. You need to use the DOM API directly.
Okay that makes way more sense, but still simpleXMLelements contains the content itself no? If i echo it json_encoded i can see the content. So in theory it should be fine to move no? However I accept your answer and appreciate the fast solution. It was very helpful understanding how it works!
No, a JSON encoded SimpleXML object does not always contain all data from the original XML. Only for specific and simple documents.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.