这个流行的 Stack Overflow 问题解释了为什么从右到左解析 CSS 选择器。 XPath 查询是否以相同的方式评估?如果这取决于实现,我会很高兴知道 libxml2 是如何做到的。
3 回答
从右到左计算路径表达式是没有意义的,几乎是不可能的:
/name1/name2/name3/name4
根据定义,这将选择作为任何元素的子元素的所有name4
元素,该name3
元素是任何元素的子name2
元素,该元素是名为 的顶部元素的子元素name1
。
这条链中的任何陈述都依赖于下一个陈述为真。因此,根据需要,评估需要从/name1
到/name1/name2
到/name1/name2/name3
最后到/name1/name2/name3/name4
这在W3C XPath 1.0 规范中明确指定:
相对定位路径由一系列以 / 分隔的一个或多个定位步骤组成。相对位置路径中的步骤从左到右组合在一起。每个步骤依次选择一组与上下文节点相关的节点。初始步骤序列与以下步骤一起组成如下。初始步骤序列选择相对于上下文节点的一组节点。 该集合中的每个节点都用作后续步骤的上下文节点。由该步骤标识的节点集被联合在一起。由步骤组成标识的节点集就是这个联合。例如,
child::div/child::para
选择上下文节点para
的div
元素子元素的子元素,或者换句话说,para
grandchildren
有div
父元素的元素。
对于您引用的问题,您应该再次仔细阅读已接受的答案。
CSS 选择器是从右到左评估的,作为浏览器具有单个元素并试图确定 CSS 样式表中的哪些选择器适用于它的特定场景的实现细节。在这种情况下,浏览器评估从右到左的原因是因为可以更快地消除候选选择器。
CSS 选择器本身并没有要求它们从右到左或从左到右进行评估。事实上,jQuery orquerySelectorAll
将从左到右进行评估,正如答案所指出的。
换句话说:
- 如果您有一个元素并且您正在测试一个选择器是否匹配它,那么将从右到左评估为一种优化通常会更快;
- 但是如果你想要所有匹配的元素,从左到右评估通常更快。
场景 1 最适合您有要设置样式的元素 (CSS) 或 XSL 样式表template match="??"
(XPath) 并且要测试大量选择器或 XPath。当您只有一个选择器或 XPath 并且您想要所有匹配的元素时,场景 2 最适合,例如当您使用querySelectorAll
或查询 DOM 时。
XPath 表达式可能比 CSS 选择器复杂得多,因此可能存在 XPath,其中从右到左的短路评估是不可能或不容易的,但从概念上讲,XSLT 引擎当然可以尝试这样做。不知道有没有
要理解的最重要的事情是,无论如何评估 CSS 选择器或 XPath,它必须给出相同的答案,就好像它在整个文档树上从左到右评估一样。因此,您不需要从左到右进行评估,但您必须表现得好像您已经这样做了,因为规范以这种方式定义了它们。
当 XSLT 使用 match="a/b/c" 形式的模式时,您有兴趣测试特定节点是否与该模式匹配,最简单的方法是从右到左。但是当 XPath 使用 select="a/b/c" 形式的表达式时,您有兴趣查找所有匹配的节点,最简单的方法是从左到右。但是,处理器没有义务(在任何一种情况下)以这种方式工作,并且很可能存在特定处理器将表达式优化为其他形式的情况。例如,给定 XPath 表达式 //a//b,处理器很可能将其重写为等效的 //b[ancestor::a],这实际上是从右到左的求值。