Макросы XSL - как создать макрос, который заменит код "call-template" - "with-param" - PullRequest
1 голос
/ 10 августа 2010

Я пытаюсь найти решение, как заменить стандартный трехстрочный код типа "call-template" - "with-param" одной строкой.

Например, у меня есть следующеекусок кода:

<xsl:call-template name="do_job">
    <xsl:with-param name="str">data1</xsl:with-param>
</xsl:call-template>

, который я хочу заменить на что-то вроде этого:

<myNs:tr name="data1"/>

Ответы [ 3 ]

3 голосов
/ 10 августа 2010

Невозможно создавать и использовать макросы в XSLT .

В XSLT 2.0 можно писать функции , используя инструкцию <xsl:function>. Затем на функцию ссылается любое выражение XPath:

my:do_job(someString)

Вот полный пример :

<xsl:stylesheet version="2.0"
 xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
 xmlns:xs="http://www.w3.org/2001/XMLSchema"
 xmlns:my="my:my">

 <xsl:template match="/">
  <xsl:sequence select="my:do_job('Hello, World!')"/>
 </xsl:template>

 <xsl:function name="my:do_job" as="xs:integer">
  <xsl:param name="pText" as="xs:string"/>

  <xsl:sequence select="string-length($pText)"/>
 </xsl:function>
</xsl:stylesheet>

когда это преобразование применяется к любому документу XML (не используется), получается правильный результат :

13
1 голос
/ 10 августа 2010

Как уже сказал Димитр, макросы не поддерживаются.Однако вы можете сгенерировать XSLT на лету из XML-документа, содержащего макросы, а затем запустить созданный XSLT.

Таблица стилей, которая создаст ваш XSLT, будет выглядеть так:

0 голосов
/ 10 августа 2010

Помимо превосходного ответа и рекомендации Dimitre, вы можете что-то вроде этой таблицы стилей:

<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:myNs="myNs"
exclude-result-prefixes="myNs">
    <myNs:tr name="data1"/>
    <myNs:tr name="data2"/>
    <xsl:template match="root">
        <root>
            <xsl:apply-templates/>
        </root>
    </xsl:template>
    <xsl:template match="data">
        <data>
            <macro>
                <xsl:apply-templates select="document('')/*/myNs:*
                                            [@name=current()]"/>
            </macro>
            <inline>
                <xsl:call-template name="do_job">
                    <xsl:with-param name="str" select="."/>
                </xsl:call-template>
            </inline>
        </data>
    </xsl:template>
    <xsl:template match="myNs:tr">
        <xsl:call-template name="do_job">
            <xsl:with-param name="str" select="@name"/>
        </xsl:call-template>
    </xsl:template>
    <xsl:template name="do_job">
        <xsl:param name="str"/>
        <xsl:value-of select="translate($str,'data','DATA')"/>
    </xsl:template>
</xsl:stylesheet>

С этим входом:

<root>
    <data>data1</data>
    <data>data2</data>
    <data>data3</data>
</root>

Выход:

<root>
    <data>
        <macro>DATA1</macro>
        <inline>DATA1</inline>
    </data>
    <data>
        <macro>DATA2</macro>
        <inline>DATA2</inline>
    </data>
    <data>
        <macro></macro>
        <inline>DATA3</inline>
    </data>
</root>

Примечание : Также я рекомендую вам прочитать FXSL Дмитрия Новатчева в http://fxsl.sf.net/

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...