您有多个问题。我将尝试一一解决:
$xpath->registerNamespace('slash', 'http://purl.org/rss/1.0/modules/slash/');
据我了解,它们的作用类似于文档定义,并且需要识别某些 XML 元素。
是的,只要您有一个带有命名空间的 XML 文档,那么每个元素都可以在它自己的命名空间中。
如果你想访问它们自己命名空间中的元素,那么是的,你需要命名空间来识别它们。例如。在 Xpath 表达式中。
在 PHP 中,DOMDocument 和其他基于 libxml 的 XML 扩展支持 XML 命名空间。
PHP 是否真的向该 URL 发出请求并验证该元素是否存在于文档定义中?
不,对于您提供的代码示例:
$xpath->registerNamespace('slash', 'http://purl.org/rss/1.0/modules/slash/');
PHP 将不会请求该 URL。您已经注意到 URL 是空的 / 给出 404,所以您可能想了解这是什么意思。该 URL 实际上是一个 URI。这就是 Identifier 和 Locator 的区别。
要使 XML 命名空间正常工作,不需要定位任何内容。只需要标识命名空间。因此,一个有效的 XML 命名空间可以用任何 URI 表示。例如,fantasy:space 是一个有效的 URI,并且完全符合指定 XML 命名空间的要求。但是当您在浏览器中输入它时,您甚至不会得到任何服务器响应(您的浏览器不知道“幻想”代表什么)。
因此,您得到的 404 并不是 Xpath 评估中斜线为空的原因:
$result = $xpath->evaluate('string(//atom:entry[3]/slash:comments)');
你在这里得到一个空字符串的原因是不同的。查看 Xpath 表达式:
string(//atom:entry[3]/slash:comments)
这是要求节点集的字符串值。您已将节点集指定为:
//atom:entry[3]/slash:comments
Getting a string of a nodeset 在 PHP DOMDocument 中的意思是:
通过在文档顺序中的第一个节点集中返回string-value of the node,将节点集转换为字符串。如果节点集为空,则返回一个空字符串。
由于节点是一个元素,所以the element node的string-value表示:
元素节点的字符串值是该元素节点的所有文本节点后代的字符串值按文档顺序串联。
所以这里有两个解释为什么你得到一个空字符串:节点集是空的或者元素字符串值只是一个空字符串。
您可以使用count() function 快速了解节点集中的节点数量:
$result = $xpath->evaluate('count(//atom:entry[3]/slash:comments)');
那么这应该让您更好地了解这两种情况中的哪一种。由于您没有共享源 XML,因此无法具体说明 why 但是它 - 正如我所假设的那样 - 不包含节点。看到来源应该很容易澄清这一点。
在那之前,我只能猜测您可能正在解析一个不包含 <atom:entry> 元素而只包含 <item> 元素的 RSS 2 提要。看我的例子:
$feed = 'http://hakre.wordpress.com/feed/';
$doc = new DOMDocument();
$doc->load($feed);
$xpath = new DOMXPath($doc);
echo $xpath->evaluate('string(//item[3]/slash:comments)'); # 1
它输出值“1”作为第三项的评论计数。这是标准 Wordpress 博客的提要。 I have put this online as an interactive example, so you can see it in action and enter your feed URL.
顺便说一句:如果您在加载 XML 之后创建 DOMXPath 对象,则无需注册命名空间 URI,只要您知道在文档。这就是为什么在示例中我没有注册任何命名空间 URI。