You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在XSLT 1.0中传递元素列表作为模板参数实现遍历?

解决XSLT 1.0中传递即时定义列表参数并遍历的问题

报错原因

在XSLT 1.0中,通过<xsl:with-param>传递的内嵌XML结构属于结果树片段(Result Tree Fragment, RTF),而非可直接遍历的节点集(Node Set)。XSLT 2.0会自动将这类结构视为节点集,所以你的代码在2.0中可行,但1.0中必须显式转换RTF为节点集才能遍历,这就是你遇到Invalid conversion from 'com.sun.org.apache.xalan.internal.xsltc.dom.SAXImpl' to 'node-set'错误的核心原因。

解决方案:用扩展函数转换RTF为节点集

Java项目常用Xalan作为XSLT处理器,可利用Xalan提供的xalan:nodeset()扩展函数完成转换。

步骤1:引入Xalan命名空间

在样式表根节点<xsl:stylesheet>中添加命名空间声明:

<xsl:stylesheet version="1.0"
    xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
    xmlns:xalan="http://xml.apache.org/xalan">

步骤2:修改Parent模板的遍历逻辑

将原模板中的遍历目标改为转换后的节点集,指定要遍历的子节点(如你的<value>节点):

<xsl:template name="Parent">
    <xsl:param name="element-list"/>
    <!-- 先将RTF转换为节点集,再遍历其中的value节点 -->
    <xsl:for-each select="xalan:nodeset($element-list)/element-list/value">
        <xsl:call-template name="Child">
            <!-- 传递当前value节点的文本或节点本身 -->
            <xsl:with-param name="element" select="."/>
        </xsl:call-template>
    </xsl:for-each>
</xsl:template>

完整代码示例

<xsl:stylesheet version="1.0"
    xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
    xmlns:xalan="http://xml.apache.org/xalan">

<xsl:template name="Child">
    <xsl:param name="element"/>
    <!-- 这里编写Child模板的处理逻辑,示例为输出元素内容 -->
    <p>处理元素:<xsl:value-of select="$element"/></p>
</xsl:template>

<xsl:template name="Parent">
    <xsl:param name="element-list"/>
    <xsl:for-each select="xalan:nodeset($element-list)/element-list/value">
        <xsl:call-template name="Child">
            <xsl:with-param name="element" select="."/>
        </xsl:call-template>
    </xsl:for-each>
</xsl:template>

<!-- 调用示例 -->
<xsl:template match="/">
    <xsl:call-template name="Parent">
        <xsl:with-param name="element-list">
            <element-list type="array">
                <value>FirstElement</value>
                <value>SecondElement</value>
            </element-list>
        </xsl:with-param>
    </xsl:call-template>
</xsl:template>

</xsl:stylesheet>

替代方案:用分隔字符串传递列表(无需扩展函数)

如果无法依赖处理器扩展,可将列表以分隔字符串形式传递,通过递归模板拆分遍历:

代码示例

<xsl:template name="Parent">
    <xsl:param name="element-string" select="''"/>
    <xsl:param name="delimiter" select="','"/>
    
    <!-- 提取第一个元素 -->
    <xsl:variable name="first-element" select="substring-before(concat($element-string, $delimiter), $delimiter)"/>
    <xsl:variable name="remaining-elements" select="substring-after($element-string, $delimiter)"/>
    
    <xsl:if test="$first-element != ''">
        <xsl:call-template name="Child">
            <xsl:with-param name="element" select="$first-element"/>
        </xsl:call-template>
        <!-- 递归处理剩余元素 -->
        <xsl:call-template name="Parent">
            <xsl:with-param name="element-string" select="$remaining-elements"/>
            <xsl:with-param name="delimiter" select="$delimiter"/>
        </xsl:call-template>
    </xsl:if>
</xsl:template>

<!-- 调用示例 -->
<xsl:call-template name="Parent">
    <xsl:with-param name="element-string" select="'FirstElement,SecondElement'"/>
</xsl:call-template>

这种方法仅适用于纯字符串列表,无需依赖扩展,但处理逻辑相对繁琐。

内容的提问来源于stack exchange,提问作者Marco Flavio Farella

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.12 04:03:11