我有一个看起来像这样的方法:
function braces(DOMElement $node){
$path = $node->getNodePath();
$xpath = new DOMXPath($node->ownerDocument);
$nodes = $xpath->query($path . '[*=(contains(., "{{") and contains(., "}}"))]');
var_dump($nodes);
}
我创建了以下两个测试用例:
$dom = new DOMDocument();
$dom->loadHTML('<div data-id="{{cat}}">
<a href="http://google.com">Google</a>
</div>',LIBXML_HTML_NODEFDTD | LIBXML_HTML_NOIMPLIED);
braces($dom->documentElement);
此var_dump()
上的{{
找不到包含}}
和object(DOMNodeList)#4 (1) {
["length"]=>
int(0)
}
的属性。
这是测试用例1的结果输出:
$dom = new DOMDocument();
$dom->loadHTML('<div data-id="{{cat}}"></div>',LIBXML_HTML_NODEFDTD | LIBXML_HTML_NOIMPLIED);
braces($dom->documentElement);
a
删除子var_dump()
元素时,{{
现在可以找到包含}}
和object(DOMNodeList)#3 (1) {
["length"]=>
int(1)
}
的属性。
这是测试用例2的结果输出:
if(a == b)
return true;
所以,我的问题是为什么当项目有孩子时它不能找到值?
答案 0 :(得分:0)
再看一下你的谓词
*=(contains(., "{{") and contains(., "}}"))
这是与两个操作数的相等比较。右侧操作数是布尔值(A和B始终是布尔值)。因此,XPath 1.0强制左侧操作数也是一个布尔值。 "*"
选择上下文节点的子节点;如果该节点集非空,即上下文节点有一个或多个子节点,则boolean(*)
为真。
所以如果(a)节点有子节点并且包含大括号,或者(b)节点没有子节点且不包含大括号,那么你的相等比较是正确的。
这里包含什么意思?如果节点的字符串值包含contains(., 'x')
作为子字符串,则表达式'x'
为true。节点的字符串值派生自节点的子节点/后代;它没有考虑属性。因为它忽略了属性,所以在这两种情况下你的contains()
测试都是假的,所以只有当左边的操作数也是假的时候,即如果节点没有子节点,谓词整体才是真的。