【问题标题】:PHP RSS XML parse, filter and display againPHP RSS XML 解析、过滤并再次显示
【发布时间】:2020-06-16 12:11:43
【问题描述】:

我正在使用DOMDocument 在 PHP 中加载 RSS XML 提要。这很好用。我需要解析我的 XML,找到特定的值,然后只再次显示某些节点​​。

XML 看起来像这样...

<rss version="2.0">
  <channel>
  <title>Title</title>
  <link></link>
  <item>
    <title>Title #1</title>
    <description>Here I want to filter</description>
  </item>
  <item>
    <title>Title #2</title>
    <description>Should not be displayed</description>
  </item>
</channel>

我想在描述标签内进行搜索,如果找到了关键字,我想显示item。如果没有找到,我想删除父item

这就是我到目前为止所尝试的......

<?php

header('Content-Type: text/xml');

// Load our XML document
$rss = new DOMDocument();
$rss->load('https://myurl');

$description = $rss->getElementsByTagName('description');

foreach ($description as $node) {
    $s = $node->nodeValue;

    if (strpos($s, 'filter') !== false)
    {
      //found the keyword, nothing to delete
    }
    else
    {
      //didnt find it, now delete item
      $node->parentNode->parentNode->removeChild($node->parentNode);
    }
}

echo $description->saveXml();

我正在尝试获取所有描述节点,检查它们是否包含字符串,如果不包含,则删除父节点。搜索字符串有效,但不能删除节点。如果我回显我的 XML,则没有任何改变。

【问题讨论】:

  • 在您的示例 XML 中,这两个项目都包含 filter,因此两者都不会被删除。
  • @NigelRen 没错。我只是改变了它来证明这个问题。在我的示例中,即使只有某些节点拥有它,它仍然无法正常工作。
  • 最后你应该使用echo $rss-&gt;saveXml();
  • @NigelRen 试过了,但仍然显示 XML。我认为 getElementsByTagName 是错误的。它返回一个 int,而不是节点。 For 循环只运行一次
  • 使用您的测试 XML(尽管已更正以添加结束 rss 标记),它会按照我的预期执行并仅显示第一项,删除 Should not be displayed 项。

标签: php xml rss


【解决方案1】:

getElementsByTagName() 将返回“实时”结果。如果您修改文档,它将更改。您可以使用iterator_to_array() 制作稳定的副本。

另一种选择是使用 Xpath 表达式来获取特定节点。

$document = new DOMDocument();
$document->loadXML($xmlString);
$xpath = new DOMXpath($document);

// fetch items that contain "filter" in their description
$items = $xpath->evaluate('/rss/channel/item[contains(description, "filter")]');
foreach ($items as $item) {
    // dump the title child element text content
    var_dump($xpath->evaluate('string(title)', $item));
} 

// fetch items that do not contain "filter" in their description
$items = $xpath->evaluate('/rss/channel/item[not(contains(description, "filter"))]');
foreach ($items as $item) {
    // remove item element
    $item->parentNode->removeChild($item);
} 
echo $document->saveXML();

输出:

string(8) "Title #1"
<?xml version="1.0"?>
<rss version="2.0">
  <channel>
  <title>Title</title>
  <link/>
  <item>
    <title>Title #1</title>
    <description>Here I want to filter</description>
  </item>

</channel>
</rss>

【讨论】:

  • 非常感谢! XPath 完美运行。我删除了 var_dump,因为 XML 在显示时出现问题。
  • 当然,这是两个例子——一个如何显示来自某些节点的数据,另一个如何删除特定节点。
  • 知道了!非常感谢你的帮助!!赞赏
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2017-12-07
  • 1970-01-01
  • 1970-01-01
  • 2012-05-03
  • 1970-01-01
  • 2012-11-21
  • 1970-01-01
相关资源
最近更新 更多