Как пропустить элемент в ленте rss, если узел `description` не существует? - PullRequest
2 голосов
/ 08 ноября 2011

Как пропустить элемент в ленте RSS, если текст description не существует?

Я попытался с этой строкой ниже, но я все еще получаю ошибку,

if($x -> item($i) -> getElementsByTagName('description')) { then proceed }

когда элемент в RSS-канале выглядит следующим образом,

<item>
    <title>Berlusconi on the brink</title>
    <link>http://www.spectator.co.uk/coffeehouse/7375408/berlusconi-on-the-brink.thtml</link>
    <guid isPermaLink="false"> http://www.spectator.co.uk/coffeehouse/7375408/berlusconi-on-the-brink.thtml </guid>
    <pubDate>Tue, 08 Nov 2011 16:42:03 +0000</pubDate>
</item>

Как видите, <description> не предоставлено.

Ниже приведена функция, которую я придумал ...

function feed_reader($url,$limit = 1,$title =  null)
{
    $xml = ($url); //http://twitter.com/statuses/friends_timeline/321998072.rss
    $xmlDoc = new DOMDocument();
    $xmlDoc -> load($xml);

    # Get and output "<item>" elements.
    $x = $xmlDoc -> getElementsByTagName('item');

    # Count the total feed with xpath.
    $xpath = new DOMXPath($xmlDoc);
    $total_feed = $xpath->evaluate('count(//item)');

    # Set feed limit.
    $limit_feed = $limit;

    # Check if the total feed is less than the limit then use the total feed as the limit.
    if($limit_feed >= $total_feed) $limit_feed = $total_feed;

    # Set the variable.
    $output = null;

    for ($i=0; $i<$limit_feed; $i++)
    {
                # Make sure that the description node exist then process.
        if($x -> item($i) -> getElementsByTagName('description'))
        {
            $item_title = $x -> item($i) -> getElementsByTagName('title') -> item(0) -> childNodes -> item(0) -> nodeValue;
            $item_link = $x -> item($i) -> getElementsByTagName('link') -> item(0) -> childNodes -> item(0) -> nodeValue;
            $item_date = $x -> item($i) -> getElementsByTagName('pubDate') -> item(0) -> childNodes -> item(0) -> nodeValue;
            $item_description = $x -> item($i) -> getElementsByTagName('description') -> item(0) -> childNodes -> item(0) -> nodeValue;

            # NOTE: use this code for the server runs PHP5.3
            # DateTime::add — Adds an amount of days, months, years, hours, minutes and seconds to a DateTime object
            $date = new DateTime($item_date);

            # change the date format into Y-m-d H:i:s
            $item_date = $date -> format('j F Y');

            # count time ago from the published date
            $time_ago = time_ago($date -> format('Y-m-d H:i:s'),'d M Y \a\t H:i');

            if($title) $output .= '<li><p>'.preg_replace('/^('.$title.':)/', ' ',limit_length(strip_tags($item_description), 200)).'<br/>'.$time_ago.'</p></li>';
                else $output .= '<li><p>'.limit_length(strip_tags($item_description), 200).'<br/>'.$time_ago.'</p></li>';

        }
    }

    return $output;

}

Ответы [ 2 ]

0 голосов
/ 08 ноября 2011

Просто используйте один запрос xpath, чтобы вернуть все элементы, которые имеют описание (как вы ищете только для них):

$xmlDoc = new DOMDocument();
$xmlDoc->loadXML($xml);
$xpath = new DOMXPath($xmlDoc);
$items = $xpath->query('/rss/item/description/..');

# Set the variable.
$output = '';

foreach($items as $number => $item)
{
    if ($number+1 >= $limit_feed) break; # enough items, limit reached

    # process each item as you see fit:

    echo $xmlDoc->saveXML($item), "\n"; # debug only for demo

    $item_title = $item->getElementsByTagName('title')->item(0)->childNodes->item(0)->nodeValue;

    # and so on ....

    if ($title) 
        $output .= '<li><p>'.preg_replace('/^('.$title.':)/', ' ',limit_length(strip_tags($item_description), 200)).'<br/>'.$time_ago.'</p></li>';
    else
        $output .= '<li><p>'.limit_length(strip_tags($item_description), 200).'<br/>'.$time_ago.'</p></li>';

}

return $output;

Демо

0 голосов
/ 08 ноября 2011

getElementsByTagName() вернет DOMNodeList, даже если он пуст. Вам нужно проверить, пусто ли оно. Кроме того, вы можете использовать xpath, как в

$xpath = new DOMXPath($x->ownerDocument);
if ($xpath->evaluate('count("description")', $x)) { ...
...