将XPath与PHP的SimpleXML一起使用以查找包含String的节点

时间:2010-09-16 11:42:36

标签: php xpath simplexml

我尝试将SimpleXML与XPath结合使用,以查找包含特定字符串的节点。

<?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

当我将第二段的xhtml更改为

<p>
    Find me!
    <br />
 </p>
然后它就像预期的那样工作。我的XPath表达式如何匹配包含“Find me”的所有节点,无论它们在哪里?

使用PHP的DOM-XML是一种选择,但不是必需的。

提前感谢!

4 个答案:

答案 0 :(得分:9)

这取决于你想做什么。您可以使用

选择其任何后代中包含“Find me”的所有<p/>元素
//xhtml:p[contains(., 'Find me')]

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

或许您希望任何包含子节点(不是后代)的节点包含“Find me”

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

这个不会返回<html/><body/>


我忘了提及.表示节点的全文内容。 text()用于检索[文本节点的节点集]。表达式contains(text(), 'Find me')的问题在于contains()仅适用于字符串,而不适用于节点集,因此会将text()转换为第一个节点的值,这就是删除第一个{{1}使它工作。

答案 1 :(得分:1)

呃,嗯?但感谢@Jordy的快速回答。

首先,这是不需要的DOM-XML,因为我的脚本中的其他内容都是使用SimpleXML完成的。

其次,为什么要翻译成大写并搜索未找到的字符串'找到我'? “搜索'找到我'实际上会给出一个结果。

但是你指出了我正确的方向:

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

诀窍!

答案 2 :(得分:1)

我一直在寻找一种方法来查找具有确切值“Find Me”的节点是否存在,这似乎有效。

$node = $xml->xpath("//text()[.='Find Me']");

答案 3 :(得分:0)

    $doc = new DOMDocument();
    $doc->loadHTML($xhtml);

    $xPath = new DOMXpath($doc);
    $xPathQuery = "//text()[contains(translate(.,'abcdefghijklmnopqrstuvwxyz', 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'), 'Find me')]";
    $elements = $xPath->query($xPathQuery);

    if($elements->length > 0){

    foreach($elements as $element){
        print "Found: " .$element->nodeValue."<br />";
    }}