Use XPath with PHP's SimpleXML to find nodes containing a String

江枫思渺然 提交于 2019-12-05 15:12:57

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')]

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

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/>.


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.

Err, umm? But thanks @Jordy for the quick answer.

First, that's DOM-XML, which is not desired, since everything else in my script is done with SimpleXML.

Second, why do you translate to uppercase and search for an unchanged string 'Find me'? 'Searching for 'FIND ME' would actually give a result.

But you pointed me towards the right direction:

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

does the trick!

I was looking for a way to find whether a node with exact value "Find Me" exists and this seemed to work.

$node = $xml->xpath("//text()[.='Find Me']");
    $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 />";
    }}
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!