PHP RSS XML 再次解析、过滤和展示

PHP RSS XML parse, filter and display again

我正在使用 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,什么都没有改变。

getElementsByTagName() 将 return 得到 "live" 结果。如果您修改文档,它将发生变化。您可以使用 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>