Dokładnie kiedy obowiązuje odwrotny kierunek osi?

Ci, którzy znają XPath, wiedzą, że niektóre osie, takie jakpreceding::, są odwrotnymi osiami. A jeśli umieścisz predykat pozycyjny na wyrażeniu zbudowanym z odwrotną osią, możesz liczyć wstecz, a nie do przodu. Na przykład.

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

zwraca poprzedni element rodzeństwa tuż przed$foo, nie pierwszy poprzedzający element rodzeństwa (w porządku dokumentu).

Ale potem występują wariacje, w których ta reguła wydaje się być zepsuta, w zależności od tego, jak daleko usunięty jest predykat pozycyjny z odwrotnej osi. Na przykład.

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

liczy do przodu od początku dokumentu, a nie od tyłu$foo.

Dzisiaj pisałem jakiś kod, w którym miałem takie wyrażenie

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

Chciałem odliczać wstecz$foo. Ale czy mój predykat pozycyjny był zbyt daleko odpreceding:: oś? Gdyby wyrażenie straciło swój odwrotny kierunek, zanim dodałem[1]? Myślałem, że to prawdopodobnie nie zadziała, więc zmieniłem go na

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

ale wtedy nie byłem pewien co do kierunku, więc w nawiasach upewniłem się, że:

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

Jednak dodatkowe nawiasy są nieco mylące i pomyślałem, że wyrażenie może być mniej wydajne, jeśli naprawdę musi liczyć od początku (dużego) dokumentu wejściowego zamiast wstecznego$foo. Czy naprawdę było to konieczne w ten sposób?

W końcu przetestowałem oryginalne wyrażenie i ku mojemu zaskoczeniu odkryłem, że zadziałało! Więc interwencja[not(parent::baz)] nie spowodował jednak, że wyrażenie straciło swój odwrotny kierunek.

Ten problem został rozwiązany, ale doszedłem do punktu, w którym chciałbym uzyskać lepszy wgląd, kiedy mogę się spodziewać odwrotnego kierunku osi. Moje pytanie brzmi:W którym punkcie (ach) wyrażenie XPath używające odwrotnej osi traci swój odwrotny kierunek?

Wierzę, że znalazłem odpowiedź teraz, więc odpowiem na moje pytanie. Ale nie mogłem znaleźć odpowiedzi na SO i jest to coś, co przeszkadzało mi wystarczająco długo, że warto było zapytać i odpowiedzieć tutaj.

questionAnswers(1)

yourAnswerToTheQuestion