PHP - getElementsByTagName('link') 即使存在于 Rss 提要中也会失败

PHP - getElementsByTagName('link') fails even when it exists in Rss feed

我想使用 PHP 解析 RSS 提要。提要有一个名为 <link> 的标签。但是当我使用 getElementsByTagName('link') 时,它 returns 标签的内容,然后当我进一步使用 -> childNodes -> nodeValue; 时,我没有得到任何结果,并且出现错误

Trying to get property of non-object

这是我正在使用的:

$xml="https://cointelegraph.com/rss"

$xmlDoc = new DOMDocument();
$xmlDoc->load($xml);

//get elements from "<channel>"
$channel=$xmlDoc->getElementsByTagName('channel')->item(0);
$channel_title = $channel->getElementsByTagName('title')->item(0)->childNodes->item(0)->nodeValue;

//Problem Causing line
$channel_link = $channel->getElementsByTagName('link')->item(0)->childNodes->item(0)->nodeValue;
//Problem Causing line

$channel_desc = $channel->getElementsByTagName('description')->item(0)->childNodes->item(0)->nodeValue;  

那个 rss 有这些标签:

<channel>
<title>Cointelegraph.com News</title>
<atom:link href="https://cointelegraph.com/rss/" rel="self" type="application/rss+xml"/>
<link>https://cointelegraph.com</link>
......
......
</channel>  

当我尝试获取 link 时,我反而获取了 atom:link

如果有另一种快速简便的解析 RSS 的方法,请在 PHP 中提出建议。

您可以获得下一个项目

$channel->getElementsByTagName('link')->item(1)->nodeValue;

你应该得到这个 url 如果那是你想要的

https://cointelegraph.com

更新

这可能是您所追求的通用解决方案。

$xml = 'https://cointelegraph.com/rss';
$xmlDoc = new DOMDocument();
$xmlDoc->load($xml);
$channel=$xmlDoc->getElementsByTagName('channel')->item(0);
$links = $channel->getElementsByTagName('link');
$channelLink = '';
for($i=0; $i < $links->length; $i++ ) {
    $link = $channel->getElementsByTagName('link')->item($i);
    if($link->hasAttribute('rel')) {// This can be replaced with what @NigelRen suggested.
        continue;
    }
    $channelLink = $channel->getElementsByTagName('link')->item($i)->nodeValue;
    break;
}

echo $channelLink;

根据其他答案的评论(应该是问题的一部分),您可以使用 XPath...

$xmlDoc = new DOMDocument();
$xmlDoc->load($xml);
$xp = new DOMXPath($xmlDoc);

//get elements from "<channel>"
$channel=$xmlDoc->getElementsByTagName('channel')->item(0);
$channel_title = $channel->getElementsByTagName('title')->item(0)->childNodes->item(0)->nodeValue;

//Problem Causing line
$channel_link = $channel->getElementsByTagName('link')->item(1)->childNodes->item(0)->nodeValue;
//Problem Causing line

echo $channel_link.PHP_EOL;

// Use XPath to get first link (not in namespace)
$channel_link = $xp->query("./link", $channel)[0]->nodeValue;
echo $channel_link;

最后一部分使用 XPath 查找 <channel> 中的任何 <link> 元素,但不涉及命名空间。

您需要创建 $xp 变量,它是靠近顶部的一行。