1

I am pulling through the BBC News XML Feed. But what I want to do is limit it to say 8 or 10 items of the feed.

How can I achieve this?

My code is :

<?php

  $doc = new DOMDocument();
  $doc->load('http://feeds.bbci.co.uk/news/rss.xml');
  $arrFeeds = array();
  foreach ($doc->getElementsByTagName('item') as $node) {
    $itemRSS = array ( 
      'title' => $node->getElementsByTagName('title')->item(0)->nodeValue,
      'desc' => $node->getElementsByTagName('description')->item(0)->nodeValue,
      'link' => $node->getElementsByTagName('link')->item(0)->nodeValue,
      'date' => $node->getElementsByTagName('pubDate')->item(0)->nodeValue
      );
?>

<h2><a href="<?php echo $itemRSS['link'] ;?>"><?php echo $itemRSS['title']; ?></a></h2>
<?php  } ?>

Thanks in advance..

StuBlackett
  • 3,789
  • 15
  • 68
  • 113

3 Answers3

7

Using XPath you can easily retrieve a subset of the RSS feed.

$itemCount = 10;
$xml = simplexml_load_file('http://feeds.bbci.co.uk/news/rss.xml');
$items = $xml->xpath(sprintf('/rss/channel/item[position() <= %d]', $itemCount));
foreach ($items as $i) {
    $itemRSS = array ( 
        'title' => (string)$i->title,
        'desc' => (string)$i->description,
        'link' => (string)$i->link,
        'date' => (string)$i->pubDate
    );
}

You be a little more lightweight by exchanging the DOM object by a SimpleXML object - and XPath is much easier to use with SimpleXML (that's why I used it in this example). The same can be achieved with DOM like that:

$doc = new DOMDocument();
$doc->load('http://feeds.bbci.co.uk/news/rss.xml');
$xpath = new DOMXpath($doc);
$items = $xpath->query(sprintf('/rss/channel/item[position() <= %d]', $itemCount));
foreach ($items as $i) {
    // ...
}
Stefan Gehrig
  • 82,642
  • 24
  • 155
  • 189
5

Take a counter variable, increment by one with each iteration and check if the counter is reached at the upper limit and then exit from loop.

$cnt=0;
foreach ($doc->getElementsByTagName('item') as $node) {
    if($cnt == 8 ) {
       break;
     }    
    $itemRSS = array ( 
      'title' => $node->getElementsByTagName('title')->item(0)->nodeValue,
      'desc' => $node->getElementsByTagName('description')->item(0)->nodeValue,
      'link' => $node->getElementsByTagName('link')->item(0)->nodeValue,
      'date' => $node->getElementsByTagName('pubDate')->item(0)->nodeValue
      );
      $cnt++;
?>    
<h2><a href="<?php echo $itemRSS['link'] ;?>"><?php echo $itemRSS['title']; ?></a></h2>
<?php 
} ?>
Shakti Singh
  • 84,385
  • 21
  • 134
  • 153
  • Wouldn't that get 9 because you are starting at 0 and incrementing at the bottom? – Ryan Matthews Oct 24 '11 at 14:14
  • @RyanMatthews: Yes, true. I just shown an example how it can be done. – Shakti Singh Oct 24 '11 at 14:15
  • @ShaktiSingh thanks for that, Works a treat. I was looking at a count var, just had it in the wrong place.. Perfect answer, Thanks. – StuBlackett Oct 24 '11 at 14:24
  • @Positive Is it possible to fetch the items randomly between the xml? Suppose, i would like to fetch the items 11 to 20 in the xml. For this, do i need to parse the entire xml, before slicing the result and displaying it? – shasi kanth Sep 05 '13 at 10:40
2

When you do it with SimpleXml, you can also use array_slice:

$rss = simplexml_load_file('http://feeds.bbci.co.uk/news/rss.xml');
$items = $rss->xpath('/rss/channel/item');
$startAtItem = 0;
$numberOfItems = 9;
$firstTenItems = array_slice($items, $startAtItem, $numberOfItems);

Or with a LimitIterator:

$rss = simplexml_load_file('http://feeds.bbci.co.uk/news/rss.xml');
$items = $rss->xpath('/rss/channel/item');
$startAtItem = 0;
$numberOfItems = 9;
$firstTenItems = new LimitIterator(
    new ArrayIterator($items), $startAtItem, $numberOfItems
);
foreach ($firstTenItems as $item) { …

More elegant is the XPath position() solution presented elsewhere on this site though.

Gordon
  • 312,688
  • 75
  • 539
  • 559