如果项目具有一个或多个子元素,则xpath不匹配

时间:2015-11-02 03:53:41

标签: php xpath

我有一个看起来像这样的方法:

function braces(DOMElement $node){
    $path   = $node->getNodePath();
    $xpath = new DOMXPath($node->ownerDocument);
    $nodes = $xpath->query($path . '[*=(contains(., "{{") and contains(., "}}"))]');

    var_dump($nodes);
}

我创建了以下两个测试用例:

测试案例1

$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);

测试案例2

a

删除子var_dump()元素时,{{现在可以找到包含}}object(DOMNodeList)#3 (1) { ["length"]=> int(1) } 的属性。

这是测试用例2的结果输出:

 if(a == b)
     return true;

所以,我的问题是为什么当项目有孩子时它不能找到值?

1 个答案:

答案 0 :(得分:0)

再看一下你的谓词

*=(contains(., "{{") and contains(., "}}"))

这是与两个操作数的相等比较。右侧操作数是布尔值(A和B始终是布尔值)。因此,XPath 1.0强制左侧操作数也是一个布尔值。 "*"选择上下文节点的子节点;如果该节点集非空,即上下文节点有一个或多个子节点,则boolean(*)为真。

所以如果(a)节点有子节点并且包含大括号,或者(b)节点没有子节点且不包含大括号,那么你的相等比较是正确的。

这里包含什么意思?如果节点的字符串值包含contains(., 'x')作为子字符串,则表达式'x'为true。节点的字符串值派生自节点的子节点/后代;它没有考虑属性。因为它忽略了属性,所以在这两种情况下你的contains()测试都是假的,所以只有当左边的操作数也是假的时候,即如果节点没有子节点,谓词整体才是真的。