I have this PHP code. The $target_xml and $source_xml variables are SimpleXMLElement objects:
$target_body = $target_xml->children($this->namespaces['main']);
$source_body = $source_xml->children($this->namespaces['main']);
foreach ($source_body as $source_child) {
foreach ($source_child as $p) {
$target_body->addChild('p', $p, $this->namespace['main']);
}
}
In the $p will be something like this XML code:
<w:p w:rsidR="009F3A42" w:rsidRPr="009F3A42" w:rsidRDefault="009F3A42" w:rsidP="009F3A42">
<w:pPr>
<w:pStyle w:val="NormlWeb"/>
// .... here is more xml tags
</w:pPr>
<w:r w:rsidRPr="009F3A42">
<w:rPr>
<w:rFonts w:ascii="Open Sans" w:hAnsi="Open Sans" w:cs="Open Sans"/>
<w:b/>
<w:color w:val="000000"/>
<w:sz w:val="21"/>
<w:szCs w:val="21"/>
</w:rPr>
<w:t>Lorem ipsum dolor sit amet...</w:t>
</w:r>
<w:bookmarkStart w:id="0" w:name="_GoBack"/>
<w:bookmarkEnd w:id="0"/>
</w:p>
The PHP code I have above will be add only this XML code to the target document:
<w:p/>
So all child nodes lost.
How can I add a child node with it's own child nodes?
SimpleXML is good for basic things, but lacks the control (and complications) of DOMDocument.
When copying content from one document to another, you have to do three things (for SimpleXML), first is convert it to a DOMElement, then import it into the target document using importNode() with true as the second argument to say do a deep copy. This just makes it available to the target document and doesn't actually place the content. This is done using appendChild() with the newly imported node...
// Convert target SimpleXMLElement to DOMElement
$targetImport = dom_import_simplexml($target_body);
foreach ($source_body as $source_child) {
foreach ($source_child as $p) {
// Convert SimpleXMLElement to DOMElement
$sourceImport = dom_import_simplexml($p);
// Import the new node into the target document
$import = $targetImport->ownerDocument->importNode($sourceImport, true);
// Add the new node to the correct part of the target
$targetImport->appendChild($import);
}
}
The SimpleXMLElement::addChild method only accepts simple values. But in this case, you are trying to add another SimpleXMLElement object.
You can check out this link that suggest the use of DOM https://stackoverflow.com/a/2356245/6824629
This is the official function documentation https://www.php.net/manual/en/function.dom-import-simplexml.php for dom_import_simplexml
Your code should look something like this:
<?php
$target_xml = new DOMDocument('1.0');
$source_body = $source_xml->children($this->namespaces['main']);
foreach ($source_body as $source_child) {
foreach ($source_child as $p) {
$dom_sxe = dom_import_simplexml($p);
// don't forget to handle your errors
$target_xml->appendChild($dom_sxe);
}
}
//you get back your target xml here
echo $target_xml->saveXML();
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With