Search code examples
phpxmlsimplexml

Converting XML file with one node using simplexml_load_string()


I have simple xml file, with one or more nodes, for examle:

<?xml version='1.0' standalone='yes'?>
<nodes>
 <node>
  <value>Val1</value>
 </node> 
</nodes>

Is it possible, using simplexml_load_string() function, for file with one node (as above) to get:

SimpleXMLElement Object
(
    [node] => Array
        (
            [0] => SimpleXMLElement Object
                (
                    [value] => Val1
                )
        )
)

with [0] key, like for a xml file with more nodes, not:

SimpleXMLElement Object
(
    [node] => SimpleXMLElement Object
        (
            [value] => Val1
        )
)

Because next I need convert it to array with the same deep, whether from a file with one or more nodes


Solution

  • SimpleXML already does what you want - the difference between the two is only in the output from print_r, which is showing the most concise way to access the elements, not the only way.

    Specifically, $xml->node->value and $xml->node[0]->value[0] can always be used to reference the same node, and foreach ( $xml->node as $node ) always works even if there is only one matching node.

    This is why it is generally a bad idea to "blindly" convert an XML structure into a PHP array - instead, use foreach loops and property access to extract whatever information you need.

    You can try it for yourself with this code:

    // Single node
    $xml1 = <<<XML
    <?xml version='1.0' standalone='yes'?>
    <nodes>
     <node>
      <value>Val1</value>
     </node> 
    </nodes>
    XML;
    
    $sx1 = simplexml_load_string($xml1);
    print_r($sx1); // misleading!
    echo $sx1->node->value, PHP_EOL;
    echo $sx1->node->value[0], PHP_EOL;
    echo $sx1->node[0]->value[0], PHP_EOL;
    echo $sx1->node[0]->value, PHP_EOL;
    foreach ( $sx1->node as $node ) {
       echo $node->value, PHP_EOL;
    }
    
    // Two nodes with same name
    $xml2 = <<<XML
    <?xml version='1.0' standalone='yes'?>
    <nodes>
     <node>
      <value>Val1</value>
     </node> 
     <node>
      <value>Val2</value>
     </node> 
    </nodes>
    XML;
    
    $sx2 = simplexml_load_string($xml2);
    print_r($sx2); // misleading!
    echo $sx2->node->value, PHP_EOL;
    echo $sx2->node[0]->value, PHP_EOL;
    echo $sx2->node[0]->value[0], PHP_EOL;
    echo $sx2->node->value[0], PHP_EOL;
    foreach ( $sx2->node as $node ) {
       echo $node->value, PHP_EOL;
    }