1

I have inherited some PHP code (but I've little PHP experience) and can't find how to count some elements in the object returned by simplexml_load_file()

The code is something like this

$xml = simplexml_load_file($feed);
for ($x=0; $x<6; $x++) {
   $title = $xml->channel[0]->item[$x]->title[0];
   echo "<li>" . $title . "</li>\n";
} 

It assumes there will be at least 6 <item> elements but sometimes there are fewer so I get warning messages in the output on my development system (though not on live).

How do I extract a count of <item> elements in $xml->channel[0]?

RedGrittyBrick
  • 3,827
  • 1
  • 30
  • 51

3 Answers3

2

Here are several options, from my most to least favourite (of the ones provided).

  • One option is to make use of the SimpleXMLIterator in conjunction with LimitIterator.

    $xml   = simplexml_load_file($feed, 'SimpleXMLIterator');
    $items = new LimitIterator($xml->channel->item, 0, 6);
    foreach ($items as $item) {
        echo "<li>{$item->title}</li>\n";
    }
    
  • If that looks too scary, or not scary enough, then another is to throw XPath into the mix.

    $xml = simplexml_load_file($feed);
    $items = $xml->xpath('/rss/channel/item[position() <= 6]');
    foreach ($items as $item) {
        echo "<li>{$item->title}</li>\n";
    }
    
  • Finally, with little change to your existing code, there is also.

    $xml = simplexml_load_file($feed);
    for ($x=0; $x<6; $x++) {
        // Break out of loop if no more items
        if (!isset($xml->channel[0]->item[$x])) {
            break;
        }
        $title = $xml->channel[0]->item[$x]->title[0];
        echo "<li>" . $title . "</li>\n";
    }
    
salathe
  • 51,324
  • 12
  • 104
  • 132
2

The easiest way is to use SimpleXMLElement::count() as:

$xml = simplexml_load_file($feed);
$num = $xml->channel[0]->count();
for ($x=0; $x<$num; $x++) {
   $title = $xml->channel[0]->item[$x]->title[0];
   echo "<li>" . $title . "</li>\n";
} 

Also note that the return of $xml->channel[0] is a SimpleXMLElement object. This class implements the Traversable interface so we can use it directly in a foreach loop:

$xml = simplexml_load_file($feed);
foreach($xml->channel[0] as $item {
   $title = $item->title[0];
   echo "<li>" . $title . "</li>\n";
} 
Martin Dimitrov
  • 4,796
  • 5
  • 46
  • 62
1

You get count by count($xml). I always do it like this:

 $xml = simplexml_load_file($feed);
 foreach($xml as $key => $one_row) {
        echo $one_row->some_xml_chield;
  } 
tasmaniski
  • 4,767
  • 3
  • 33
  • 65
  • OK, but 6 is an upper limit for display, I guess I can use `if $count++ >= 6 { break; }` inside the loop. – RedGrittyBrick Sep 21 '11 at 19:59
  • Hey, I just find function **simpleXMLToArray** there [link](http://php.net/manual/en/book.simplexml.php). You can pass xml object to this function and get array, and than you can pass throw element by for($i=0;$i>...){ ... } – tasmaniski Sep 21 '11 at 20:22