你有多个问题。我将尝试一一解决:
$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
在 PHP DOMDocument 中获取节点集的字符串意味着:
通过返回节点集中在文档顺序中排在第一位的节点的字符串值,将节点集转换为字符串。如果节点集为空,则返回一个空字符串。
由于节点是一个元素,元素节点的字符串值意味着:
元素节点的字符串值是该元素节点的所有文本节点后代的字符串值按文档顺序串联而成。
所以这里有两个解释为什么你会得到一个空字符串:节点集是空的,或者元素字符串值只是一个空字符串。
count()
您可以使用以下函数快速了解节点集中的节点数:
$result = $xpath->evaluate('count(//atom:entry[3]/slash:comments)');
那么这应该让您更好地了解这两种情况中的哪一种。由于您没有共享源 XML,因此无法具体说明为什么它 - 正如我所假设的那样 - 不包含节点。看到来源应该很容易澄清这一点。
在那之前,我只能猜测您可能正在解析一个不包含<atom:entry>
元素而只包含元素的 RSS 2 提要<item>
。看我的例子:
$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 博客的提要。我已将此作为交互式示例放到网上,因此您可以看到它的实际效果并输入您的提要 URL。
顺便说一句:如果您在加载 XML后DOMXPath
创建对象,则无需注册命名空间 URI,只要您知道文档中使用了哪些前缀即可。这就是为什么在示例中我没有注册任何命名空间 URI。