PHP - SimpleXML - AddChild with another SimpleXMLElement
As far as I know, you can't do it with SimpleXML because addChild
doesn't make a deep copy of the element (being necessary to specify the tag name can easily be overcome by calling SimpleXMLElement::getName()
).
One solution would be to use DOM instead:
With this function:
function sxml_append(SimpleXMLElement $to, SimpleXMLElement $from) {
$toDom = dom_import_simplexml($to);
$fromDom = dom_import_simplexml($from);
$toDom->appendChild($toDom->ownerDocument->importNode($fromDom, true));
}
We have for<?php
header("Content-type: text/plain");
$sxml = simplexml_load_string("<root></root>");
$n1 = simplexml_load_string("<child>one</child>");
$n2 = simplexml_load_string("<child><k>two</k></child>");
sxml_append($sxml, $n1);
sxml_append($sxml, $n2);
echo $sxml->asXML();
the output<?xml version="1.0"?>
<root><child>one</child><child><k>two</k></child></root>
See also some user comments that use recursive functions and addChild
, e.g. this one. In SimpleXML, how can I add an existing SimpleXMLElement as a child element?
I know this isn't the most helpful answer, but especially since you're creating/modifying XML, I'd switch over to using the DOM functions. SimpleXML's good for accessing simple documents, but pretty poor at changing them.
If SimpleXML is treating you kindly in all other places and you want to stick with it, you still have the option of jumping over to the DOM functions temporarily to perform what you need to and then jump back again, using dom_import_simplexml()
and simplexml_import_dom()
. I'm not sure how efficient this is, but it might help you out.
Why php simplexml allow addChild in one of these examples but not the other?
In your first instance, you're thinking that $xml->RequestHeader
refers to the <ns:RequestHeader/>
node in your source, but it doesn't. You could have used any fake name with no change in the output of $xml->asXML()
; So you get a warning when you try to add a child because $header
is not actually a member of your $xml
tree.
In the second instance, you're adding the child directly to the $xml
tree that was parsed, so you get no warning:
$header = $xml->addChild('RequestHeader');
It seems that the SimpleXML ->
operator is not designed to sort out your ns:
flags. Your first code block works if you remove them from $base
$base = '<?xml version="1.0" encoding="UTF-8"?>' . "\n" .
'<RootNode xmlns="http://www.bogus.com/bogus/">' .
'<RequestHeader/>' .
'<ContractInfo/>' .
'</RootNode>' . "\n";
$xml = simplexml_load_string($base);
$header = $xml->RequestHeader;
$header->addChild('SourceID', '123456');
echo $xml->asXML() . "\n\n";
This raises no warning Add child to xml with PHP simpleXml
then, you should not create new items node:
$xml = simplexml_load_file("myxml.xml");
$sxe = new SimpleXMLElement($xml->asXML());
$itemsNode = $sxe->items[0];
$itemsNode->addChild("item", $newValue);
$sxe->asXML("myxml.xml");
Is there a way to add a PHP SimpleXMLElement to another SimpleXMLElement?
Hey unknown. You have to use the DOMElement interface to your SimpleXML objects to achieve this.
<?php
$s = new SimpleXMLElement('<root/>');
$t = new DOMElement('child');
$dom = dom_import_simplexml($s);
$dom->appendChild($t);
echo $s->asXML();
// <root><child/></root>
If you need more specific details, let me know. There are several examples in the documentation and comments for the dom_import_simplexml() method too: http://php.net/dom_import_simplexml SimpleXMLElement::addChild() is not working
Please try this. The problem is that addChild()
of simplexmlelement expects a string and you are trying to append an object which it typecasts to null.
You need to use DOM andpublic SimpleXMLElement SimpleXMLElement::addChild ( string $name [, string $value [, string $namespace ]] )
appendChild
to DOM instead.function sxml_append(SimpleXMLElement $to, SimpleXMLElement $from) {
$toDom = dom_import_simplexml($to);
$fromDom = dom_import_simplexml($from);
$toDom->appendChild($toDom->ownerDocument->importNode($fromDom, true));
}
$parent = new SimpleXMLElement('<review_sr><status>Review Complete</status><payheads><payhead><code>ABAS</code><old_value>0.00</old_value><new_value>63570.00</new_value><review_id>1234567890</review_id><review_time>20160614:11:00:47</review_time><status>Accepted</status></payhead></payheads><current_gross_allowance>50481.00</current_gross_allowance><review_gross_allowance>114051.00</review_gross_allowance></review_sr>');
$child = new SimpleXMLElement('<source><payhead><code>DMG</code><old_value>500.00</old_value><new_value>0.00</new_value><review_id>1234567890</review_id><review_time>20160620:12:41:17</review_time><status>Accepted</status></payhead></source>');
$child = $child->xpath('//payhead'); //This is to ignore the xml declaration that is automatically produced by the SimpleXMLElement constructor
$child = $child[0]; //I've tried LIBXML_NOXMLDECL but its not working, that's why these two lines.
$parentNode = $parent->xpath('//payheads');
sxml_append($parentNode[0],$child[0]);
var_dump($parent);
Insert XML structure as a child of another XML Element using PHP
You can't with SimpleXML, but if you really need manipulate your DOM or create it from scratch consider DOMDocument.
$xmlObject = new \DOMDocument();
$xml = $xmlObject->createElement('root');
$xml_a = $xmlObject->createElement('parent');
$xml_b = $xmlObject->createElement('child');
$xml_b->setAttribute('attribute','value');
$xml_b->appendChild(new \DOMElement('item', 'itemValue'));
$xml_a->appendChild($xml_b);
$xml->appendChild($xml_a);
$xmlObject->appendChild($xml);
echo $xmlObject->saveXML();
SimpleXML: append one tree to another
You can't add a "tree" directly using SimpleXML, as you have seen. However, you can use some DOM methods to do the heavy lifting for you whilst still working on the same underlying XML.
$xmldict = new SimpleXMLElement('<dictionary><a/><b/><c/></dictionary>');
$kitty = new SimpleXMLElement('<cat><sound>meow</sound><texture>fuzzy</texture></cat>');
// Create new DOMElements from the two SimpleXMLElements
$domdict = dom_import_simplexml($xmldict->c);
$domcat = dom_import_simplexml($kitty);
// Import the <cat> into the dictionary document
$domcat = $domdict->ownerDocument->importNode($domcat, TRUE);
// Append the <cat> to <c> in the dictionary
$domdict->appendChild($domcat);
// We can still use SimpleXML! (meow)
echo $xmldict->c->cat->sound;
Related Topics
How to Connect an Oracle Database from PHP
How to Run a Whois Lookup with PHP or Python
Php: Require Path Does Not Work for Cron Job
Rounding Up to the Second Decimal Place
Encoding Byte Data into Digits
Check If the Current Date Is Between Two Dates + MySQL Select Query
How to Get Content of Remote HTML Page
How to Access Magento Customer's Session from Outside Magento
Check If SQL Row Exists with PHP
How to Upload Files in Web Workers Without Using Formdata
Randomize a PHP Array with a Seed
Calculating Working Hours Between Two Dates
Cannot Set Date.Timezone in PHP.Ini File
PHP - Regex - How to Extract a Number with Decimal (Dot and Comma) from a String (E.G. 1,120.01)