如何在XPath查询的一部分中匹配两个元素之一

时间:2018-12-10 02:27:41

标签: php xpath

我已经使用php DOMXPath查询锚点,并且想要匹配两个元素之一。我目前正在使用管道或条件进行此操作:

//div[@class="wrapper"]//div[@class="target"]/a | //div[@class="wrapper"]//li[@class="target"]/a

这有效。我也尝试过此操作(如here所述):

//div[@class="wrapper"]//*[self::div or self::li][@class="target"]/a

虽然起作用,但它似乎效率不高,因为它使用通配符查询每个元素,然后在事后过滤它们。

为简明扼要,我想知道是否有可能缩短我的原始查询,以便我的|条件仅适用于特定部分,而不是重复整个查询。我以为我可以做这样的事情,但是会引发错误DOMXPath::query(): Invalid expression

//div[@class="wrapper"]//(div|li)[@class="target"]/a

使用正确的语法是否可行?还是需要针对每种情况明确说明整个路径?

1 个答案:

答案 0 :(得分:1)

//div[@class="wrapper"]//(div|li)[@class="target"]/a是有效的 XPath 2.0 表达式,但不是 XPath 1.0 。您的PHP引擎可能会降级为 XPath 1.0

如果您担心第二个XPath //div[@class="wrapper"]//*[self::div or self::li][@class="target"]/a的性能,请第一个配置文件并进行度量,以查看其性能是否在可接受的范围内。您可能会发现它的性能足够好,或与第一个示例相同,并且您不必担心它们之间的差异。

您还可以测试和衡量性能的替代方法是在谓词测试divli元素之前将谓词限制移动到具有等于“ target”的类属性的元素: / p>

//div[@class="wrapper"]//*[@class="target"][self::div or self::li]/a

或将它们组合成一个谓词:

//div[@class="wrapper"]//*[@class="target" and (self::div or self::li)]/a