从RSS错误中删除项目

时间:2014-08-04 16:23:43

标签: php dom rss

如果超过8天,我使用以下PHP从我拥有的XML中删除项目。它曾经工作过一次,但现在给我错误信息

  

在非对象中调用成员函数removeChild()   /Users//DateTest-3.php第40行

第40行是

$node->parentNode->removeChild($node);

为什么这会引发错误?

<?php

$rss = new DOMDocument();
$url = 'http://URL.com/Test.xml';
$rss->load($url);
$feed = array();
foreach ($rss->getElementsByTagName('item') as $node) {
    $item = 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('date')->item(0)->nodeValue,
    );
    array_push($feed, $item);
}

$limit = 50;
for ($i = 0; $i < count($feed); $i++) {
    date_default_timezone_set('America/Los_Angeles');
    $newDate = strtotime("-8 day");
    $date = strtotime($feed[$i]['date']);
    if ($date > $newDate) {
        echo "Don't delete";
    } else {
        echo "Delete";
        $node->parentNode->removeChild($node);
    }
}

$rss->save("Test.xml")




?>

3 个答案:

答案 0 :(得分:1)

  • 在RSS 1.0中,没有&#39; date&#39;关于物品。但是&lt; dc; date&#39;发挥作用。 http://web.resource.org/rss/1.0/spec#s5.5

  • 在RSS 2.0中没有&#39; date&#39;,但&#39; pubdate&#39;关于物品。 http://cyber.law.harvard.edu/rss/rss.html#hrelementsOfLtitemgt

  • 决定,如果您想查找&#39; date&#39;,&#39; dc:date&#39;并且&#39; pubDate&#39;。以下代码适用于pubDate。

  • $limit = 50;未使用

  • 在迭代下从nodeList中删除节点将不起作用。这是一顶旧帽子!请参阅此处的评论:http://php.net/manual/de/domnode.removechild.php解决方案是使用队列标记坏节点,然后将其删除。

  • 我冒昧地修改了代码。我故意激活了调试内容。主要用于日期比较和减少列表显示。代码已注释。

  • 请调整Feed网址和&#34; -x天数&#34;在这种情况下。我不得不使用公共RSS提要来测试。

-

<?php

date_default_timezone_set('America/Los_Angeles');

$feed = array(); // target array for filtered items

$nodesToRemoveQueue = array(); // stores all nodes to remove

$rss = new DOMDocument();
$url = 'http://rss.nytimes.com/services/xml/rss/nyt/Space.xml';
$rss->load($url);

$nodeList = $rss->getElementsByTagName('item');

foreach ($nodeList as $node)
{
    $pubDate = $node->getElementsByTagName('pubDate')->item(0)->nodeValue;

    // if date in the xml feed is older then desired number of days, remove node
    // and proceed with iteration. (do not transfer the data into the $feeds array.)
    if(isDateOlderThenDays($pubDate, '-5 days')) {
        echo 'Removed ' . $pubDate . '<br>';
        // $node->parentNode->removeChild($node); this won't work!!
        $nodesToRemoveQueue[] = $node; // put node in queue, remove later
        continue;
    }

    echo 'Kept ' . $pubDate . '<br>';

    // build item for $feed array, then add item to $feed array
    $item = array (
        'title' => $node->getElementsByTagName('title')->item(0)->nodeValue,
        'desc' => $node->getElementsByTagName('description')->item(0)->nodeValue,
        'link' => $node->getElementsByTagName('link')->item(0)->nodeValue,
        'date' => $pubDate,
    );

    $feed[] = $item;
}

// helper to compare dates -
function isDateOlderThenDays($date, $days)
{
    // when pubdate($date) is lower(older) then $days, return true, else false.
    return (strtotime($date) < strtotime($days)) ? true : false;
}

// feed array contains all the not "outdated" items
var_dump($feed);

// finally: remove the "outdated" nodes
foreach($nodesToRemoveQueue as $node){
  $node->parentNode->removeChild($node);
}

// nodelist reduction check. this should only displays the dates kept
$nodeList = $rss->getElementsByTagName('item');
foreach ($nodeList as $node) {
    echo $node->getElementsByTagName('pubDate')->item(0)->nodeValue . '<br>';
}

// write reduced RSS XML to file
$rss->save(__DIR__.'/Test.xml');

另一种保存XML的方法是:

$xmlString = $rss->saveXML();
file_put_contents(__DIR__.'/Test.xml', $xmlString);

答案 1 :(得分:0)

是否故意只在

之后的最后一个节点上工作
foreach ($rss->getElementsByTagName('item') as $node)

因为$node与最后$rss->getElementsByTagName('item')作业保持一致。 或者代码丢失了吗?

答案 2 :(得分:0)

在您的第二个foreach中,在每次迭代时重新分配$node。例如。 $node = $feed[$i]