使用PHP DOMXpath和通配符时排除HTML属性

时间:2012-05-15 17:51:56

标签: php xpath joomla

我正在尝试使用PHP DOMXpath在Joomla网站上匹配多个字符串,并使用如下查询:

$query = "//*[contains(text(),'$target'))]";

HTML标记的一个示例如下:

<ul>
  <li>
    <a href="#" title="foo bar"><span>foo bar</span></a>
 </li>
</ul>

整个PHP函数(为清晰起见而修改)是:

function onAfterRender() {

    $buffer = JResponse::getBody();

    $doc = new DOMDocument;
    $doc->loadHTML($buffer);
    $xpath = new DOMXPath($doc);

    $targets = 'Foo, foo';
    $targets = explode(',', $targets);

     foreach ($targets as $target) {

         $query = $xpath->evaluate("//*[contains(.,'" . trim($target) . "')]");

         foreach($query as $match) {

            $match = $doc->saveXML($match);

            $replacement = preg_replace("/($target)/i",'<i class="notranslate">' . $target. '</i>',$match);

            $buffer = str_replace($match, $replacement, $buffer);

            JResponse::setBody($buffer);
        }

     }

    return true;
}

有什么想法吗?

谢谢!

编辑:我之前没有明确说过的问题是,当使用这种方法注入HTML时,就像foo一样,会产生无效的标记。如果没有“破坏”给访问者,这个无效的标记可能会很糟糕。我想排除匹配title属性和可能的​​其他元素,如title标签等。

编辑:我已经更新了原始问题和代码。部分解决方案是更改$ match = $ doc-&gt; saveXML($ match);因为它保留了HTML标记。但是,我无法排除HTML属性,但可以使用进一步的正则表达式省略这些匹配。

1 个答案:

答案 0 :(得分:0)

缺少标题中的等号=“foo”

<ul>
  <li>
    <a href="#" title="foo"><span>fooey</span></a>
 </li>
</ul>

这似乎对我有用:

    $body = JResponse::getBody();
    // test
    $doc = new DOMDocument;
    $doc->loadHTML($body);
    $xpath = new DOMXPath($doc);
    $targets = 'Foo, foo';
    $targets = explode(',', $targets);

     foreach ($targets as $target) {

         $query = "//*[contains(text(),'".trim($target)."')]";
         echo $query .'<br>';

         foreach($xpath->query($query) as $match) {

            $match = $match->textContent;
            echo 'match: ' . $match .'<br>';

        }

     }

输出:

//*[contains(text(),'Foo')]
//*[contains(text(),'foo')]
match: fooey