如果超过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")
?>
答案 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]
。