Question

I'm parsing xml nodes and I'm doing something wrong but I don't know what. I have this xml:

$xml="    <root>
        <info>
        <company/>
        <user_id>43</user_id>
        <currency>EUR</currency>
        </info>
        <products>
         <product>
          <id>1336</id>
          <pn>NX.RZNAA.003</pn>
          <stock>1.00</stock>
         </product>
         <product>
          <id>1337</id>
          <pn>NX.RZNAA.004</pn>
          <stock>4.00</stock>
          <item_number>5</item_number>
         </product>
        </products>
     </root>";

As you can see I have two "product" nodes with child nodes. But in first node "product" I have one node less then in second. In second the node "item_number" is added (it's optional node, if it has value it is in xml otherwise not) . When I'm parsing this nodes my parser returns value from second nodes "product" even if I'm on first node.

Anyone know what is the problem here?

Here is my code:

$xmlDoc = new DOMDocument();
$xmlDoc->load($xml) ; 
$xpath = new DOMXPath($xmlDoc);
$tagForCount="count(//".$arrayPolja[0].")"; 
$x=$xmlDoc->getElementsByTagName("product");
$xpath = new DomXpath($xmlDoc);
$count = 3;
$arrayPolja[0] = "id";
$arrayPolja[1] = "pn";
$arrayPolja[2] = "stock";
$arrayPolja[3] = "item_number";
$r=0;
foreach ($x as $product) {
     $i=0;
     while ($i<=$count)
     {
        $polje=$arrayPolja[$i];
        $values[$i]=$xpath->query($polje, $product)->item($r)->textContent;     
        $i++;
     }
    $r++;
}
Was it helpful?

Solution

For one, the second iteration in the loop is overriding the values of your array "$values" which is why you'd only be seeing the values from the second product node (if you are inspecting the "$values" array which is what I'm assuming you are doing).

Try this:

$xmlDoc = new DOMDocument();
$xmlDoc->load($xml); 
$xpath = new DOMXPath($xmlDoc);
$x = $xmlDoc->getElementsByTagName("product");
$array = array('id','pn','stock','item_number');
$values = array();

foreach ($x as $product) {
    $data = array();

    // node name here
    $data['node'] = $product->nodeName;

    foreach ($array as $v){
        $obj = $xpath->query($v, $product)->item(0);
        if (gettype($obj) == 'object'){
            $data[$v] = $obj->textContent; 
        }  
    }
    $values[] = $data;
}
echo '<pre>' . print_r($values, true). '</pre>';

That should produce this:

Array
(
[0] => Array
    (
        [node] => product
        [id] => 1336
        [pn] => NX.RZNAA.003
        [stock] => 1.00
    )

[1] => Array
    (
        [node] => product
        [id] => 1337
        [pn] => NX.RZNAA.004
        [stock] => 4.00
        [item_number] => 5
    )
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top