【发布时间】: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 的 <div> 类型的元素,例如 <div class="note-editable mayhaveanotherclasstoo">。
我试过了:
$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 <div> 标记的占位符仍然被替换。
知道我尝试的查询有什么问题吗?
编辑
最小可重现 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);
【问题讨论】: