XSL 1.0
От: fk0 Россия https://fk0.name
Дата: 08.02.23 12:07
Оценка:
Немедленно нажми на RESET, All!

Я правильно понимаю, что в XSL 1.0 нет возможности, например, реализовать что-то вроде функции?

Если кратко; хочется в шаблон передать параметром шаблона другой шаблон, который этот шаблон
параметризирует вычисленными из текущего узла значениями и вызовет.

Например, во входном документе есть элементы, над которыми хочется провести вычисления и получить
ряд переменных, которые передать параметром в заданный шаблон. В один, другой, третий, пятый,
десятый. И вот это всё тоже должно быть, стало быть, шаблоном. Но в XSL 1.0 невозможно шаблон
сделать параметром шаблона, т.к. параметр name в xsl:call-template не может быть переменной,
а должен быть непосредственным значением.

Есть известный способ выкрутиться, вместо call-template использовать apply-templates и
задать параметром select="document('')/*/template[@name='$param']". Но получается, что содержимое
выбранного таким образом темплейта будет интерпретироваться как текст и узлы из xsl там не
будут обрабатываться. Да вообще любые узлы. По крайней мере так получается в xsltproc.

По-моему эта проблема имеет тесное отношение к другой: мол как применить шаблон к уже
сгенерированному результату преобразования. Например, через xsl:copy. Тоже никак. И здесь
такая-же история.

Я знаю, что в XSLT 2.0 и других процессорах есть миллион разных способов, но пользуясь чистым
XSLT 1.0 остаётся только разве что, в шаблоне-функции, из которой хочется вызвать другой шаблон,
в конце писать гигантский xsl:choose и там выбирать какую конкретно функцию вызвать, в зависимости
от входного параметра. Я правильно понимаю?
Re: XSL 1.0
От: Mr.Delphist  
Дата: 08.02.23 14:34
Оценка:
Здравствуйте, fk0, Вы писали:

fk0> Есть известный способ выкрутиться, вместо call-template использовать apply-templates и

fk0>задать параметром select="document('')/*/template[@name='$param']". Но получается, что содержимое
fk0>выбранного таким образом темплейта будет интерпретироваться как текст и узлы из xsl там не
fk0>будут обрабатываться. Да вообще любые узлы. По крайней мере так получается в xsltproc.

Не совсем понимаю сценарий — поделитесь примером? Вроде бы можно передавать как значения переменных, так и узлы XML? Типа такого:
    <xsl:call-template name="MyTemplate">
     <xsl:with-param name="param1" select="$variable1" /> <!-- значение переменной -->
     <xsl:with-param name="param2" select="./subItems" /> <!-- узел XML-потока -->
    </xsl:call-template>


fk0> По-моему эта проблема имеет тесное отношение к другой: мол как применить шаблон к уже

fk0>сгенерированному результату преобразования. Например, через xsl:copy. Тоже никак. И здесь
fk0>такая-же история.

Да, в первой версии есть входной поток (который, однако, может содержать несколько документов), и есть выходной поток, который всегда описывает один-единственный документ. Помню, выкручивался через последовательный вызов XSLT-трансформаций, когда во входном потоке часть документов — это результаты работы предыдущих трансформаций, с заранее известными именами (что приводит нас к ситуации, что нельзя файл перезаписать в себя же как результат трансформации — имена должны быть разные, иначе ошибка записи в залоченный файл).

fk0> Я знаю, что в XSLT 2.0 и других процессорах есть миллион разных способов, но пользуясь чистым

fk0>XSLT 1.0 остаётся только разве что, в шаблоне-функции, из которой хочется вызвать другой шаблон,
fk0>в конце писать гигантский xsl:choose и там выбирать какую конкретно функцию вызвать, в зависимости
fk0>от входного параметра. Я правильно понимаю?

Сам по себе гигантский choose не обязателен — серия описаний корневых шаблонов <xsl:template match="что-то-там"> уже является таким набором, и XSLT-процессор будет поочерёдно (сверху вниз) пытаться сматчить перечисленные шаблоны с текущим узлом входного XML-потока (причём это может работать в том числе и рекурсивно, в функциональном стиле). Соответственно, шаблон с match="/" должен всегда идти последним, иначе на него будет матчиться всё подряд, каждый узел — вряд ли это то что хочется.
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.