2011-01-24 4 views
3

나는 다음과 같은 html을 가지고있다 :왜 span {2}가 문서의 두 번째 스팬을 선택하지 않습니까?

<!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> 

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 

왜 이런 일이 발생합니까?

답변

6

볼이 몸을보십시오. 원래 xpath 쿼리를 다음과 같이 읽어야합니다.

//(span[2]) 

즉, 문서의 모든 곳에서 동일한 부모 요소의 두 번째 범위 요소를 찾습니다.

대신 (//span)[2]으로 작성하면 모든 범위 요소를 찾은 다음 두 번째 범위를 선택합니다.

+2

적절히 말하자면,이 축약 된 형태가 다음과 같이 확장 될 것이기 때문에, * 퍼센티지 * 참여가 없습니다 (파서의 문법 프로덕션에 대해 말하지 않는다면 ...)./descendant-or-self :: node()/child :: span [position() = 2]'와'fn : position()'은 ax (이 경우에는 암시적인 자식)에 대해 작용합니다. '(/ span) [2]'는 짧은 표현식이지만 .../descendant :: span [2]'이 더 명확하고 최적화에 개방적이라는 것에 동의 할 수 있습니다. –

2

//span[1]은 스팬 부모의 첫 번째 스팬 요소를 참조하기 때문에. 실제로이 기준에 부합하는 4 개가 있습니다 (모두 4 개). .singleNodeValue

//span[2]이 (가) 부모의 두 번째 자녀를 나타내는 기간을 요청할 때만 표시됩니다.

[2]//로 높은 우선 순위를 가지고

<body> 
<p>A <span>one</span></p> 
<p>B <span>two</span></p> 
<p>C <span>three</span></p> 
<p>D <span>four</span><span>five</span></p> 
</body> 
+0

수정 프로그램은 SQL Server XPath에서 작동하지만 JS XPath에 대해서는 확실하지 않습니다.'(// span [1]) [2] ' – RichardTheKiwi

+0

대단히 감사합니다. 나는 Elian의 답변을 약간 더 명확하게 받아 들였습니다. 예제는 정말 유용합니다. –

관련 문제