Вот случай, когда этого недостаточно:
<a>
<b>
<c>
<c>
<c/>
</c>
</c>
</b>
<c>
<c>
<c/>
</c>
</c>
</a>
Теперь я хочу соответствовать только:
*[self::a or self::b][p(.)]/c/descendent-or-self::c
то есть, если предикат p (.) Истинен для a, я хочу a / c, a / c / c, a / c / c / c, и если это верно для b, я хочу b / c, b / c / c, и b / c / c / c.
Но я не хочу a / b / c, a / b / c / c и т. Д. Только потому, что предикат совпадает с a, а не с b.
Если я сделаю шаблон совпадения:
*[self::a or self::b][p(.)]//c
тогда я сопоставляю их всех, чего не хочу.
Так что я должен сделать это в скобках назад:
c[ancestor-or-self::c/parent::*[self::a or self::b][p(.)]]
Мне кажется, я просто убедил себя, что это ограничение не является логическим ограничением, однако я считаю оправдание не допускать правильных шагов оси в шаблонах совпадений довольно неубедительным, потому что, когда мне это нужно, мне нужно это, кто заботится, если это не так быстро, как если бы я использовал более простые выражения.