如果您可以切换到 xslt 2.0,那么用户功能将正是您所需要的。
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:fn="http://www.w3.org/2005/xpath-functions" xmlns:my="my-namespace">
<xsl:output method="text" version="1.0" encoding="UTF-8" indent="yes"/>
<xsl:template match="/">
<xsl:value-of select="my:complexWidget(1, 2, 3, 4)" />
</xsl:template>
<xsl:function name="my:complexWidget">
<xsl:param name="a" />
<xsl:param name="b" />
<xsl:param name="c" />
<xsl:param name="d" />
<!-- Do something -->
<xsl:value-of select="($a, $b,$c, $d)" separator="-" />
</xsl:function>
</xsl:stylesheet>
在 xslt 1.0 中,我认为使用另一种转换对 xslt 样式表进行预处理将是唯一的方法(或者可能是用处理器的语言编写一些扩展函数。
编辑:
我尝试了 xslt 的“预处理”,它似乎正在工作(但它可能不是最优雅的方式)。
输入 xslt
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:mypp="my-preprocess-namespace">
<xsl:output method="text" />
<xsl:template match="/">
<xsl:variable name="varA" select="1"/>
<xsl:variable name="varB" select="2"/>
<xsl:variable name="varC" select="3"/>
<xsl:variable name="varD" select="4"/>
<mypp:complexWidget a="$varA" b="$varB" c="$varC" d="$varD"/>
</xsl:template>
<xsl:template name="complexWidget">
<xsl:param name="a"/>
<xsl:param name="b"/>
<xsl:param name="c"/>
<xsl:param name="d"/>
<!-- do something-->
<xsl:value-of select="$a"/>
<xsl:text>-</xsl:text>
<xsl:value-of select="$b"/>
<xsl:text>-</xsl:text>
<xsl:value-of select="$c"/>
<xsl:text>-</xsl:text>
<xsl:value-of select="$d"/>
</xsl:template>
</xsl:stylesheet>
我在这里为要替换的元素定义了一个特殊的命名空间(即xmlns:mypp="my-preprocess-namespace"
)。要替换的元素是<mypp:complexWidget a="$varA" b="$varB" c="$varC" d="$varD"/>
。
我使用以下 xslt 预处理这个 xslt。
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:mypp="my-preprocess-namespace">
<xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes"/>
<xsl:template match="node() | @*">
<xsl:copy>
<xsl:apply-templates select="node() | @*" />
</xsl:copy>
</xsl:template>
<xsl:template match="mypp:*">
<xsl:element name="xsl:call-template">
<xsl:attribute name="name">
<xsl:value-of select="local-name()" />
</xsl:attribute>
<xsl:for-each select="@*">
<xsl:element name="xsl:with-param">
<xsl:attribute name="name">
<xsl:value-of select="name()" />
</xsl:attribute>
<xsl:attribute name="select">
<xsl:value-of select="." />
</xsl:attribute>
</xsl:element>
</xsl:for-each>
</xsl:element>
</xsl:template>
</xsl:stylesheet>
它基于“身份转换” ——将所有内容复制到输出,只是将特殊命名空间中的元素转换为调用模板元素。我想这可以比我做得更好。
输出是
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:mypp="my-preprocess-namespace" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
<xsl:output method="text" />
<xsl:template match="/">
<xsl:variable name="varA" select="1"/>
<xsl:variable name="varB" select="2"/>
<xsl:variable name="varC" select="3"/>
<xsl:variable name="varD" select="4"/>
<xsl:call-template name="complexWidget">
<xsl:with-param name="a" select="$varA"/>
<xsl:with-param name="b" select="$varB"/>
<xsl:with-param name="c" select="$varC"/>
<xsl:with-param name="d" select="$varD"/>
</xsl:call-template>
</xsl:template>
<xsl:template name="complexWidget">
<xsl:param name="a"/>
<xsl:param name="b"/>
<xsl:param name="c"/>
<xsl:param name="d"/>
<!-- do something-->
<xsl:value-of select="$a"/>
<xsl:text>-</xsl:text>
<xsl:value-of select="$b"/>
<xsl:text>-</xsl:text>
<xsl:value-of select="$c"/>
<xsl:text>-</xsl:text>
<xsl:value-of select="$d"/>
</xsl:template>
</xsl:stylesheet>
当我将输出作为 xslt 样式表运行时,它会产生预期的输出。
但是我对通过另一个 xslt 生成 xslt 样式表没有任何更深入的经验,所以我不太了解这种方法可能出现的问题。