aspring
aspring

Reputation: 125

How do I skip an RSS item if field empty?

Another little thing has been driving me crazy... I want to pull in an RSS feed and display it using PHP. It asks for the mrss decription (because it doesn't have all the extra junk attached to it). The only problem is that the feed has advertisements. So when the script calls for the media description of an advertisement (for which there is none), the whole page fails.

I've tried using continue and an if...else based on length, but it's still not working..

$xml=("http://feeds.abcnews.com/abcnews/gmavideos");
$xmlDoc = new DOMDocument();
$xmlDoc->load($xml);
$x=$xmlDoc->getElementsByTagName('item');

for ($i=0; $i<=10; $i++)
  {
  $item_title=$x->item($i)->getElementsByTagName('title')
  ->item(0)->childNodes->item(0)->nodeValue;
  $item_link=$x->item($i)->getElementsByTagNameNS('http://www.pheedo.com/namespace/pheedo', 'origLink')
  ->item(0)->childNodes->item(0)->nodeValue;
  $item_desc=$x->item($i)->getElementsByTagNameNS('http://search.yahoo.com/mrss/', 'description')
  ->item(0)->childNodes->item(0)->nodeValue;

    if ($x->length == 0) {
        exit('etc.');
    }
    else {
  echo ("<p><a href='" . $item_link
  . "' target='_blank'>" . $item_title . "</a>");
  echo ("<br />");
  echo ($item_desc . "</p>");
  }
  }

Any guidance appreciated!

Upvotes: 2

Views: 517

Answers (3)

Dimitre Novatchev
Dimitre Novatchev

Reputation: 243479

The only problem is that the feed has advertisements. So when the script calls for the media description of an advertisement (for which there is none), the whole page fails.

Use:

/*/channel/item[media:description]

Or, alternatively:

/*/channel/item[not(title='Advertisement:')]

I personally would use and recommend the first expression above.

Upvotes: 0

Adam Fowler
Adam Fowler

Reputation: 1751

if ($item_title=="") continue;

Upvotes: 0

Francis Avila
Francis Avila

Reputation: 31631

Without seeing the error message I can't know for sure, but most likely the script is failing because of this line:

$item_desc=$x->item($i)->getElementsByTagNameNS('http://search.yahoo.com/mrss/', 'description')->item(0)->childNodes->item(0)->nodeValue;

If there is no description element, then getElementsByTagNameNS() will return an empty DOMNodeList, so the ->item(0)->childNodes will fail.

You need to separate these out.

$item_desc_nodes = $x->item($i)->getElementsByTagNameNS('http://search.yahoo.com/mrss/', 'description');
if ($item_desc_nodes->length) {
    $item_desc = $item_desc_nodes->item(0)->childNodes->item(0)->nodeValue;
} else {
    continue;
}

Honestly, though, you should really be using XPath instead of getElementsByTagNameNS.

You should also use ->textContent instead of ->childNodes->item(0)->nodeValue.

UPDATE: This is how I would accomplish the same task using XPath

$xml = 'http://feeds.abcnews.com/abcnews/gmavideos';
$xmlDoc = new DOMDocument();
$xmlDoc->load($xml);

$xpath = new DOMXPath($xmlDoc);
$xpath->registerNamespace('media', 'http://search.yahoo.com/mrss/');
$xpath->registerNamespace('pheedo', 'http://www.pheedo.com/namespace/pheedo');

// filter out the ads in the xpath expression itself by saying there must be
// a pheedo:origLink element in the item
$items = $xpath->query('/rss/channel/item[pheedo:origLink][position() < 11]');

$linktmpl = '<p><a href="%s" target="_blank">%s</a><br />%s</p>'."\n";

foreach($items as $item) {
    $item_title = $xpath->evaluate('string(title)', $item);
    $item_link = $xpath->evaluate('string(pheedo:origLink)', $item);
    $item_desc = $xpath->evaluate('string(media:description)', $item);

    $escaped = array_map('htmlspecialchars', array($item_link, $item_title, $item_desc));
    vprintf($linktmpl, $escaped);
}

Upvotes: 3

Related Questions