Как применить или объединить несколько подходящих шаблонов в XSLT? - PullRequest
3 голосов
/ 08 мая 2010

Я работаю над таблицей стилей, используя множество шаблонов с атрибутами соответствия:

<xsl:template match="//one" priority="0.7">
   <xsl:param name="input" select="."/>
   <xsl:value-of select="util:uppercase($input)"/>
   <xsl:next-match />
</xsl:template>

<xsl:template match="/stuff/one">
    <xsl:param name="input" select="."/>
    <xsl:value-of select="util:add-period($input)"/>
</xsl:template>

<xsl:function name="util:uppercase">
    <xsl:param name="input"/>
    <xsl:value-of select="upper-case($input)"/>
</xsl:function>

<xsl:function name="util:add-period">
    <xsl:param name="input"/>
    <xsl:value-of select="concat($input,'.')"/>
</xsl:function>

Что я хотел бы сделать, так это уметь «связать» две функции выше, так что вход «string» будет отображаться в выходных данных как «STRING». (с точкой.) Я хотел бы сделать это таким образом, чтобы не требовалось знание других шаблонов в любом другом шаблоне. Так, например, я хотел бы иметь возможность добавить метод "util: add-colon", не открывая капот и обезьяны с существующими шаблонами.

Я играл с инструкцией <xsl:next-match/>, чтобы выполнить это. Добавление его в первый шаблон выше, конечно, вызывает как util: uppercase, так и util: add-period, но вывод представляет собой агрегацию каждого вывода шаблона (то есть 'STRINGstring.'). Кажется, должен быть элегантный способ цепочки любое количество шаблонов вместе, используя что-то вроде <xsl:next-match/>, но выходные данные каждого шаблона передают вход следующего в цепочке. Я пропускаю что-то очевидное?

1 Ответ

3 голосов
/ 08 мая 2010

Цепочка шаблонов может быть выполнена путем захвата вывода template1 в xsl:variable, затем применения template2 к содержимому этой переменной xsl:.

Однако я 'рекомендую использовать функциональную композицию :

util:add-period(util:uppercase(.))

Кроме того, вы можете добиться желаемого эффекта, если вы слегка измените util:add-period():

Использование:

<xsl:function name="util:add-period" as="xs:string">  
    <xsl:text>.</xsl:text>  
</xsl:function>
...