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.