使用 XPath 和 PHP 的 SimpleXML 查找包含字符串的节点 [英] Use XPath with PHP's SimpleXML to find nodes containing a String

查看:29
本文介绍了使用 XPath 和 PHP 的 SimpleXML 查找包含字符串的节点的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我尝试结合使用 SimpleXML 和 XPath 来查找包含特定字符串的节点.

I try to use SimpleXML in combination with XPath to find nodes which contain a certain string.

<?php
$xhtml = <<<EOC
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
    "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="de" lang="de">
    <head>
        <meta http-equiv="content-type" content="text/html; charset=utf-8" />
        <title>Test</title>
    </head>
    <body>
        <p>Find me!</p>
        <p>
            <br />
            Find me!
            <br />
        </p>
    </body>
</html>
EOC;

$xml = simplexml_load_string($xhtml);
$xml->registerXPathNamespace('xhtml', 'http://www.w3.org/1999/xhtml');

$nodes = $xml->xpath("//*[contains(text(), 'Find me')]");

echo count($nodes);

预期输出:2实际输出:1

Expected output: 2 Actual output: 1

当我把第二段的xhtml改成

When I change the xhtml of the second paragraph to

<p>
    Find me!
    <br />
 </p>

然后它按预期工作.我的 XPath 表达式必须如何匹配包含查找我"的所有节点,无论它们在哪里?

then it works like expected. How has my XPath expression has to look like to match all nodes containing 'Find me' no matter where they are?

使用 PHP 的 DOM-XML 是一种选择,但不是我们想要的.

Using PHP's DOM-XML is an option, but not desired.

提前致谢!

推荐答案

这取决于你想做什么.您可以选择所有 <p/> 元素的任何后代中包含Find me"的

It depends on what you want to do. You could select all the <p/> elements that contain "Find me" in any of their descendants with

//xhtml:p[contains(., 'Find me')]

这将返回重复项,因此您不指定节点的类型,然后它将返回 <body/><html/> 作为嗯.

This will return duplicates and so you don't specify the kind of nodes then it will return <body/> and <html/> as well.

或者您可能想要任何具有包含Find me"的子(不是后代)文本节点的节点

Or perhaps you want any node which has a child (not a descendant) text node that contains "Find me"

//*[text()[contains(., 'Find me')]]

这个不会返回 .

This one will not return <html/> or <body/>.

我忘了提到 . 代表一个节点的整个文本内容.text() 用于检索 [a nodeset of] 文本节点.您的表达式 contains(text(), 'Find me') 的问题在于 contains() 仅适用于字符串,而不适用于节点集,因此它会转换 text() 到第一个节点的值,这就是为什么删除第一个
使其工作.

I forgot to mention that . represents the whole text content of a node. text() is used to retrieve [a nodeset of] text nodes. The problem with your expression contains(text(), 'Find me') is that contains() only works on strings, not nodesets and therefore it converts text() to the value of the first node, which is why removing the first <br/> makes it work.

这篇关于使用 XPath 和 PHP 的 SimpleXML 查找包含字符串的节点的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆