Unfortunately, SimpleXMLElement does not offer anything to combine the two elements. As @nickf wrote , it is more suitable for reading than for manipulation. However, the DOMDocument sister DOMDocument is for editing, and you can combine them together via dom_import_simplexml() . And @salathe shows in the corresponding answer how this works for certain SimpleXMLElements.
The following shows how this works with input validation and some additional parameters. I am doing this with two examples. The first example is a function to insert an XML string:
/** * Insert XML into a SimpleXMLElement * * @param SimpleXMLElement $parent * @param string $xml * @param bool $before * @return bool XML string added */ function simplexml_import_xml(SimpleXMLElement $parent, $xml, $before = false) { $xml = (string)$xml; // check if there is something to add if ($nodata = !strlen($xml) or $parent[0] == NULL) { return $nodata; } // add the XML $node = dom_import_simplexml($parent); $fragment = $node->ownerDocument->createDocumentFragment(); $fragment->appendXML($xml); if ($before) { return (bool)$node->parentNode->insertBefore($fragment, $node); } return (bool)$node->appendChild($fragment); }
This sample function allows you to add XML or insert it before a specific element, including the root element. Upon learning whether there is anything to add, it uses the functions and methods of DOMDocument to insert XML as a fragment of a document, also outlined in How to Import an XML String into PHP DOMDocument . Usage example:
$parent = new SimpleXMLElement('<parent/>'); // insert some XML simplexml_import_xml($parent, "\n <test><this>now</this></test>\n"); // insert some XML before a certain element, here the first <test> element // that was just added simplexml_import_xml($parent->test, "\n ", $before = true); // you can place comments above the root element simplexml_import_xml($parent, "", $before = true); // but take care, you can produce invalid XML, too: // simplexml_add_xml($parent, "<warn><but>take care!</but> you can produce invalid XML, too</warn>", $before = true); echo $parent->asXML();
This gives the following result:
<?xml version="1.0"?> <parent> <test><this>now</this></test> </parent>
The second example is the insertion of SimpleXMLElement . If necessary, it uses the first function. It basically checks if there is anything to do at all and which item should be imported. If it is an attribute, it will simply add it; if it is an element, it will be serialized in XML and then added to the parent element as XML:
/** * Insert SimpleXMLElement into SimpleXMLElement * * @param SimpleXMLElement $parent * @param SimpleXMLElement $child * @param bool $before * @return bool SimpleXMLElement added */ function simplexml_import_simplexml(SimpleXMLElement $parent, SimpleXMLElement $child, $before = false) { // check if there is something to add if ($child[0] == NULL) { return true; } // if it is a list of SimpleXMLElements default to the first one $child = $child[0]; // insert attribute if ($child->xpath('.') != array($child)) { $parent[$child->getName()] = (string)$child; return true; } $xml = $child->asXML(); // remove the XML declaration on document elements if ($child->xpath('/*') == array($child)) { $pos = strpos($xml, "\n"); $xml = substr($xml, $pos + 1); } return simplexml_import_xml($parent, $xml, $before); }
This sample function normalizes the list of elements and attributes, such as common in Simplexml. You might want to change it to insert several SimpleXMLElements at once, but as the usage example shows, my example does not support this (see the Attributes example):
// append the element itself to itself simplexml_import_simplexml($parent, $parent); // insert <this> before the first child element (<test>) simplexml_import_simplexml($parent->children(), $parent->test->this, true); // add an attribute to the document element $test = new SimpleXMLElement('<test attribute="value" />'); simplexml_import_simplexml($parent, $test->attributes()); echo $parent->asXML();
This is a continuation of the first use case. Therefore, the output is now:
<?xml version="1.0"?> <parent attribute="value"> <this>now</this><test><this>now</this></test> <parent> <test><this>now</this></test> </parent> </parent>
Hope this is helpful. You can find the code in essence and an online demo / Overview of the PHP version .