【问题标题】:DOMXPath multiple contain selectors not workingDOMXPath 多个包含选择器不起作用
【发布时间】:2019-12-06 06:40:18
【问题描述】:

我有以下 XPath 查询,SO 上的一位好心用户帮助了我:

$xpath->query(".//*[not(self::textarea or self::select or self::input) and contains(., '{{{')]/text()") as $node)

其目的是将某些占位符替换为一个值,并正确捕获以下不应被替换的事件:

<textarea id="testtextarea" name="testtextarea">{{{variable:test}}}</textarea>

并正确替换这样的事件:

<div>{{{variable:test}}}</div>

现在,除了文本区域、选择或输入之外,我想排除在该查询中包含类名称 note-editable&lt;div&gt; 类型的元素,例如 &lt;div class="note-editable mayhaveanotherclasstoo"&gt;

我试过了:

$xpath->query(".//*[not(self::textarea or self::select or self::input) and not(contains(@class, 'note-editable')) and contains(., '{{{')]/text()") as $node)

和:

$xpath->query(".//*[not(self::textarea or self::select or self::input or contains(@class, 'note-editable')) and contains(., '{{{')]/text()") as $node)

我已就一些与此类似的问题遵循了建议:PHP xpath contains class and does not contain class,并且我没有收到 PHP 错误,但 note-editable &lt;div&gt; 标记的占位符仍然被替换。

知道我尝试的查询有什么问题吗?

编辑

最小可重现 DOM 样本:

<div class="note-editing-area">
    <textarea class="note-codable"></textarea>
    <div class="note-editable panel-body" contenteditable="true" style="height: 350px;">{{{variable:system_url}}</div>
</div>

进行替换的代码:

$dom = new DOMDocument();
libxml_use_internal_errors(true);
$dom->loadHTML($html);
$xpath = new DOMXpath($dom);
foreach ($xpath->query(".//*[not(self::textarea or self::select or self::input or self::div[contains(@class,'note-editable')]) and contains(., '{{{')]/text()") as $node) {
    $node->nodeValue = preg_replace_callback('~{{{([^:]+):([^}]+)}}}~', function($m) use ($placeholders) {
        return $placeholders[$m[1]][$m[2]] ?? '';
    },
    $node->nodeValue);
}
$html = $dom->saveHTML();
echo html_entity_decode($html);

【问题讨论】:

    标签: dom xpath domxpath


    【解决方案1】:

    在 xpath 下使用它。

    .//*[not(self::textarea or self::select or self::input or self::div[contains(@class,'note-editable')]) and contains(., '{{{')]
    

    【讨论】:

    • 不幸的是,这不起作用。我的问题已更新为最小可重现的 DOM 片段以及执行​​替换的代码。提前感谢您的帮助。
    • 我明白了为什么它不起作用——
      元素是在页面呈现后通过 JS 创建的。没有这个要求,你的答案是有效的。因此接受为正确。
    最近更新 更多