首页 > 解决方案 > PHP RSS XML 解析、过滤并再次显示

问题描述

我正在使用 PHP 加载 RSS XML 提要DOMDocument。这很好用。我需要解析我的 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. 如果找不到,我想删除 parent 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,则没有任何变化。

标签: phpxmlrss

解决方案


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>

推荐阅读