代码之家  ›  专栏  ›  技术社区  ›  xlttj

使用XPath和PHP的SimpleXML查找包含字符串的节点

  •  4
  • xlttj  · 技术社区  · 14 年前

    我尝试结合使用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);
    

    实际产量:1

    当我把第二段的xhtml改为

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

    然后它像预期的那样工作。为了匹配包含“Find me”的所有节点(无论它们在哪里),XPath表达式的外观如何?

    提前谢谢你!

    4 回复  |  直到 14 年前
        1
  •  9
  •   Josh Davis    14 年前

    <p/> 在其任何子代中包含“Find me”的元素

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

    <body/> <html/> 也。

    或者,您希望任何节点具有包含“Find me”的子(不是子代)文本节点

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

    这个不会再回来了 <html/> <正文/>


    我忘了提那件事 . 表示节点的整个文本内容。 text() contains(text(), 'Find me') contains() 只在字符串上工作,不在节点集上工作,因此它会转换 文本() 第一个节点的值,这就是删除第一个节点的原因 <br/>

        2
  •  1
  •   xlttj    14 年前

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

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

    第二,为什么要翻译成大写并搜索一个不变的字符串“Find me”搜索“找到我”实际上会给出一个结果。

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

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

    真有办法!

        3
  •  1
  •   Willy    12 年前

    $node = $xml->xpath("//text()[.='Find Me']");
    
        4
  •  0
  •   user443346 user443346    14 年前
        $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 />";
        }}