views:

131

answers:

2

I'm trying to add a child to an XML-node by loading a string as an xml-node, but for some reason it returns an empty value ...

// Load xml
$path = 'path/to/file.xml';
$xml = simplexml_load_file($path);

// Select node
$fields = $xml->sections->fields;

// Create new child node
$nodestring = '<option>
           <label>A label</label>
           <value>A value</value>
           </option>';

// Add field
$fields->addChild('child_one', simplexml_load_string($nodestring));

For some reason, child_one is added but without content, although it does put in the line-breaks.

Although when I do a var_export on simplexml_load_string($nodestring), I get:

    SimpleXMLElement::__set_state(array(
   'label' => 'A label',
   'value' => 'A value',
    ))

So I'm not sure what I'm doing wrong ...

EDIT:

Sample xml-file:

<config>
    <sections>
        <fields>
            text
        </fields>
    </sections> 
</config>

Sampe $xml -file after trying to add child node:

<config>
    <sections>
        <fields>
            text
        <child_one>


</child_one></fields>
    </sections> 
</config>
+1  A: 

SimpleXML cannot manipulate nodes. You can create new nodes from values, but you cannot create a node then copy this node to another document.

Here are three solutions to that problem:

  1. Use DOM instead.
  2. Create the nodes in the right document directly, e.g.

    $option = $fields->addChild('option');
    $option->addChild('label', 'A label');
    $option->addChild('value', 'A value');
    
  3. Use a library such as SimpleDOM, which will let you use DOM methods on SimpleXML elements.

In your example, solution 2 seems the best.

Josh Davis
Thanks, I found that I can load the string with DOMDocument->loadXML, then select a node from that xml file and copy it to another XML file(see my own answer if anybody is interested)
Rakward
A: 

Code I used:

// Load document
$orgdoc = new DOMDocument;
$orgdoc->loadXML("<root><element><child>text in child</child></element></root>");

// Load string
$nodestring = '<option>
       <label>A label</label>
       <value>A value</value>
       </option>';

$string = new DOMDocument;
$string->loadXML($nodestring);

// Select the element to copy
$node = $string->getElementsByTagName("option")->item(0);

// Copy XML data to other document
$node = $orgdoc->importNode($node, true);
$orgdoc->documentElement->appendChild($node);
Rakward
If you want to use DOM, then you can use appendXML() too -- http://docs.php.net/manual/en/domdocumentfragment.appendxml.php
Josh Davis