Considere este documento XML:
<foo>
<bar id="aaa"/>
<jam>
<bar id="bbb"/>
</jam>
</foo>
Estou tentando encontrar o primeiro <bar>
elemento no documento.
Aqui está o que descobri:
Teste# | Expressão XPath | Expressão de Avaliação | Resultado |
---|---|---|---|
1 | //bar |
@id |
aaa ,bbb |
2 | //bar[1] |
@id |
aaa ,bbb |
3 | (//bar)[1] |
@id |
aaa |
O que não entendo é por que o Teste nº 2 retorna aaa
, bbb
em vez de apenas aaa
. É como se a [1]
operadora não estivesse funcionando.
Meu entendimento foi que no Teste nº 2, a //bar
expressão encontraria os dois nós e então o [1]
operador escolheria o primeiro. Obviamente, estou faltando alguma coisa.
Isso parece ser confirmado pelo Teste nº 3, que aparentemente é como expressar o que eu realmente quero.
Além disso, se você alterar o documento XML para isto:
<foo>
<bar id="aaa"/>
<bar id="bbb"/>
</foo>
então você consegue o que eu esperava ver:
Teste# | Expressão XPath | Expressão de Avaliação | Resultado |
---|---|---|---|
1 | //bar |
@id |
aaa ,bbb |
2 | //bar[1] |
@id |
aaa |
3 | (//bar)[1] |
@id |
aaa |
Que sutileza estou faltando aqui sobre como [1]
deve funcionar?
A especificação XPath contém esta nota sobre a
//
sintaxe abreviada:IOW, se você quiser selecionar o primeiro
bar
elemento do documento você precisa usar:em vez de:
Ao contrário das outras respostas, não estou afirmando que faça sentido.
Em
//bar[1]
, o predicado[1]
é anexado à etapachild::bar
e avaliado no contexto dessa etapa. O predicado, portanto, pergunta se o nó em questão é o primeiro filho de seu pai , e não se é o primeiro de todos os nós que seriam selecionados por//bar
. Este último é o que(//bar)[1]
significa.