Соответствие шаблону XSLT: рецепт перемещения запрещенных осей в предикат

Я понимаю, что стандарт XSLT 1.0 запрещает использование большинства осей XPath в части StepPatern. выражение совпадения. (См. этот вопрос, где рекомендуемая альтернатива использовал нужную ось в предикате.)

У меня есть сложное выражение XPath, которое возвращает набор узлов node-set-expression. Я хочу создать шаблон, соответствующий node-set-expression/ following-sibling::*. Есть ли общий способ переписать это для использования предикатов, чтобы его можно было использовать в атрибуте match элемента XSLT template?

И, что эквивалентно, есть ли общий способ перевести следующее:

node-set-expression/ preceding-sibling::*

node-set-expression/ self-and-following-sibling::* (это сокращение; я знаю, что это не допустимая ось)

Если предикаты не работают, есть ли другие общие подходы?


person dlh    schedule 27.11.2013    source источник
comment
Можете ли вы включить образец XML-файла, шаблон для узла, с которого вы сопоставляетесь, и какой узел вы хотите настроить?   -  person    schedule 28.11.2013


Ответы (1)


В XSLT 2.0 я обычно обрабатываю такие случаи, предварительно выбирая соответствующие узлы в глобальной переменной:

<xsl:variable name="special-nodes" select="//something/preceding-sibling::*"/>

<xsl:template match="*[. intersect $special-nodes]"/>

В XSLT 3.0 это еще больше упростится до

<xsl:template match="$special-nodes"/>

Преимущество этого способа заключается в том, что однократный поиск «специальных узлов», вероятно, будет намного более эффективным, чем проверка каждого узла на соответствие каждому такому шаблону при выполнении применения шаблонов; это также делает условие более ясным, на мой взгляд.

Единственное известное мне общее решение вашего вопроса для XSLT 1.0 - написать шаблон как

<xsl:template match="*[count(.|//something/preceding-sibling::*) =
                       count(//something/preceding-sibling::*)]">

но это действительно слишком ужасно неэффективно, чтобы созерцать.

person Michael Kay    schedule 28.11.2013