为什么// span [2]没有选择文档中的第二个跨度?

Stu*_*t K 3 html javascript xpath

我有以下html:

<!doctype HTML>
<html>
<head>
 <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
 <title>Test</title>
</head>
<body>

<p>A <span>one</span></p>

<p>B <span>two</span></p>

<p>C <span>three</span></p>

<p>D <span>four</span></p>

</body>
</html>
Run Code Online (Sandbox Code Playgroud)

运行XPath //span[1]获得第一个跨度.但是//span[2]返回null:

 input: document.evaluate("//span[1]", document, null, XPathResult.FIRST_ORDERED_NODE_TYPE, null).singleNodeValue
output: <span>?one?</span>?

 input: document.evaluate("//span[2]", document, null, XPathResult.FIRST_ORDERED_NODE_TYPE, null).singleNodeValue
output: null
Run Code Online (Sandbox Code Playgroud)

为什么会这样?

Eli*_*ing 6

[2]具有更高的优先级为//.您应该将原始xpath查询读取为:

//(span[2])
Run Code Online (Sandbox Code Playgroud)

这意味着,它在文档中的任何位置查找同一父元素的第二个span元素.

如果你(//span)[2]改为编写,它将在任何地方寻找span元素,然后选择第二个span.

  • 正确地说,没有*优先级*涉及(除非你谈论解析器的语法生成......)因为这个缩写形式将扩展为:`/ descendant-or-self :: node()/ child: :span [position()= 2]`和`fn:position()`对抗ax(在这种情况下隐式`child`).人们可以同意`(// span)[2]`是一个简短的表达式...但是`/ descendant :: span [2]`它更清晰,更开放于优化. (2认同)