如何实现多输入多输出的XSLT函数?含节点与项输入输出需求
问题解答
首先明确:XSLT 2.0及以上版本的自定义函数完全支持返回包含转换后节点+所有输入参数的多类型序列。
关键原理
XSLT函数的返回值是item()*类型的序列,序列中可以混合包含节点(node())、原子项(比如字符串、数字等item()子类),你要的"多输出"本质就是返回一个包含多种元素的序列。
修正后的实现示例
原代码中嵌套<xsl:template match="Trans"/>属于语法错误(模板不能嵌套在模板/函数内部),下面是改成XSLT函数的正确写法:
<?xml version="1.0" encoding="utf-8"?> <xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:ns0="http://ecs.dgtaxud.ec" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:fn="http://www.w3.org/2005/xpath-functions" xmlns:custom="http://example.com/custom-functions"> <!-- 自定义函数的命名空间 --> <!-- 自定义函数:接收多类型参数,返回包含转换节点+所有输入的序列 --> <xsl:function name="custom:Test" as="item()*"> <xsl:param name="Trans" select="()" as="node()*"/> <xsl:param name="cont" select="()" as="item()*"/> <xsl:param name="num" select="()" as="item()*"/> <xsl:param name="Sl" select="()" as="node()*"/> <xsl:param name="id" select="()" as="item()*"/> <xsl:param name="GRef" select="()" as="node()*"/> <xsl:param name="dNum" select="()" as="item()*"/> <!-- 1. 生成转换后的节点(替换原嵌套模板的逻辑) --> <xsl:variable name="transformed-nodes"> <xsl:for-each select="$Trans"> <xsl:element name="{name(..)}" namespace="{namespace-uri(..)}"> <xsl:copy-of select="../(* except $Sl)"/> <!-- 原代码的current-group()需结合分组逻辑,这里假设处理单个Trans节点,可按需调整 --> <xsl:copy-of select="."/> </xsl:element> </xsl:for-each> </xsl:variable> <!-- 2. 返回序列:转换后的节点 + 所有输入参数 --> <xsl:sequence select="$transformed-nodes/node(), $Trans, $cont, $num, $Sl, $id, $GRef, $dNum"/> </xsl:function> </xsl:stylesheet>
注意事项
- 自定义函数必须放在独立的命名空间下(比如示例中的
custom:前缀),避免和内置函数冲突。 - 返回序列时使用
<xsl:sequence select="..."/>,可以一次性输出所有需要的内容,包括节点和原子项。 - 原代码中的
current-group()依赖<xsl:for-each-group>分组逻辑,如果你的转换需要分组,需在函数内部补充对应的分组代码。
内容的提问来源于stack exchange,提问作者RamAlx
相关产品推荐
相关产品推荐

