代码之家  ›  专栏  ›  技术社区  ›  Eaten by a Grue kackleyjm

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

  •  1
  • Eaten by a Grue kackleyjm  · 技术社区  · 6 年前

    我已经使用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 回复  |  直到 6 年前
        1
  •  1
  •   Eaten by a Grue kackleyjm    6 年前

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

    如果您担心第二个xpath的性能 //div[@class="wrapper"]//*[self::div or self::li][@class="target"]/a ,首先分析并测量它是否在可接受的范围内执行。您可能会发现它的性能足够好,或者与第一个示例相同,并且您不需要担心差异。

    您还可以测试和度量性能的替代方法是,在谓词测试之前,将谓词限制为类属性等于“target”的元素。 div li 元素:

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

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

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