Exatamente quando a direção reversa de um eixo se aplica?

Aqueles que estão familiarizados com XPath sabem que alguns eixos, comopreceding::são eixos invertidos. E se você colocar um predicado posicional em uma expressão construída com um eixo reverso, poderá estar contando para trás em vez de para frente. Por exemplo.

$foo/preceding-sibling::*[1]

retorna o elemento irmão anterior pouco antes$foo, não o primeiro elemento irmão precedente (na ordem do documento).

Mas então você encontra variações onde esta regra parece estar quebrada, dependendo de quão distante está o predicado posicional do eixo reverso. Por exemplo.

($foo/preceding-sibling::*)[1]

conta para frente a partir do início do documento, não para trás$foo.

Hoje eu estava escrevendo algum código onde eu tinha uma expressão como

$foo/preceding::bar[not(parent::baz)][1]

Eu queria contar para trás$foo. Mas foi meu predicado posicional muito longe dopreceding:: eixo? Se a expressão tivesse perdido a direção inversa antes de adicionar o[1]? Eu pensei que provavelmente não funcionaria, então eu mudei para

$foo/preceding::bar[not(parent::baz)][last()]

mas então eu não tinha certeza da direção, então coloquei parênteses para ter certeza:

($foo/preceding::bar[not(parent::baz)])[last()]

No entanto, os parênteses extras são um pouco confusos, e eu pensei que a expressão pode ser menos eficiente, se realmente tem que contar a partir do início do documento de entrada (grande) em vez de para trás de$foo. Foi realmente necessário fazer assim?

Finalmente testei a expressão original e descobri, para minha surpresa, que funcionava! Então a intervenção[not(parent::baz)] não fez a expressão perder a direção inversa, afinal.

Esse problema foi resolvido, mas cheguei ao ponto em que gostaria de ter um melhor controle sobre quando posso esperar que a direção inversa de um eixo seja aplicada. Minha pergunta é:Em que ponto (s) uma expressão XPath usando um eixo reverso perde sua direção inversa?

Eu acredito que encontrei a resposta agora, então responderei a minha própria pergunta. Mas eu não consegui encontrar a resposta no SO, e é algo que me incomoda o tempo suficiente para valer a pena perguntar e responder aqui.

questionAnswers(1)

yourAnswerToTheQuestion