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

XSLT遍历现有数组创建新数组问题求助

XSLT 3.0 数组收集问题解决

问题根源

原代码无法正常工作的核心原因:

  • XSLT采用不可变变量模型,for-each内部定义的$myArray是局部变量,不会修改外部同名变量,导致外部的$myArray始终为空数组,后续遍历循环无法执行。
  • 代码中array:append($myArray, personName)存在变量引用错误,personName未加$符号,无法正确引用已定义的变量。
  • 未使用给定的map数据源,而是硬编码了输入数组。

修正后的代码

以下是针对给定map数据源,正确收集人员名称到数组的XSLT代码:

<xsl:stylesheet
    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:map="http://www.w3.org/2005/xpath-functions/map"
    xmlns:array="http://www.w3.org/2005/xpath-functions/array"
    version="3.0">
    <xsl:output method="text"/>
    <xsl:strip-space elements="*" />

    <xsl:template name="test" match="/">
        <xsl:param name="data" select="map {
            'persons': [
                map {'name': 'John', 'age': 33, 'residence':'Permanent'},
                map {'name': 'Peter', 'age': 36, 'residence':'Temporary'}
            ]
        }"/>
        
        <!-- 从map中获取persons数组,提取所有name字段生成新数组 -->
        <xsl:variable name="myArray" select="array:map(map:get($data, 'persons'), function($person) {
            map:get($person, 'name')
        })"/>

        <!-- 遍历输出新数组内容 -->
        <xsl:for-each select="1 to array:size($myArray)">
            <xsl:text>Person name is : </xsl:text>
            <xsl:value-of select="array:get($myArray, .)"/>
            <xsl:text>&#10;</xsl:text> <!-- 换行 -->
        </xsl:for-each>
    </xsl:template>
</xsl:stylesheet>

代码说明

  1. 数据源处理:通过map:get($data, 'persons')从传入的map参数中获取人员数组。
  2. 数组转换:使用array:map函数遍历人员数组的每个元素,提取name字段值,直接生成包含所有名称的新数组,这是XSLT 3.0中处理数组转换最简洁的函数式方式。
  3. 数组遍历输出:通过1 to array:size($myArray)遍历新数组,逐个输出人员名称。

如果坚持使用手动循环的方式(不推荐,函数式方式更简洁高效),可以使用递归模板构建数组:

<xsl:stylesheet
    xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
    xmlns:xs="http://www.w3.org/2001/XMLSchema"
    xmlns:map="http://www.w3.org/2005/xpath-functions/map"
    xmlns:array="http://www.w3.org/2005/xpath-functions/array"
    version="3.0">
    <xsl:output method="text"/>
    <xsl:strip-space elements="*" />

    <xsl:template name="test" match="/">
        <xsl:param name="data" select="map {
            'persons': [
                map {'name': 'John', 'age': 33, 'residence':'Permanent'},
                map {'name': 'Peter', 'age': 36, 'residence':'Temporary'}
            ]
        }"/>
        
        <xsl:variable name="personsArray" select="map:get($data, 'persons')"/>
        <!-- 调用递归模板构建名称数组 -->
        <xsl:variable name="myArray">
            <xsl:call-template name="build-name-array">
                <xsl:with-param name="inputArray" select="$personsArray"/>
                <xsl:with-param name="currentArray" select="array{}"/>
            </xsl:call-template>
        </xsl:variable>

        <!-- 遍历输出 -->
        <xsl:for-each select="1 to array:size($myArray)">
            <xsl:text>Person name is : </xsl:text>
            <xsl:value-of select="array:get($myArray, .)"/>
            <xsl:text>&#10;</xsl:text>
        </xsl:for-each>
    </xsl:template>

    <!-- 递归模板:遍历输入数组,收集名称到新数组 -->
    <xsl:template name="build-name-array">
        <xsl:param name="inputArray"/>
        <xsl:param name="currentArray"/>
        
        <xsl:if test="array:size($inputArray) > 0">
            <!-- 获取第一个元素的name -->
            <xsl:variable name="firstName" select="map:get(array:get($inputArray, 1), 'name')"/>
            <!-- 追加到当前数组 -->
            <xsl:variable name="updatedArray" select="array:append($currentArray, $firstName)"/>
            <!-- 递归处理剩余元素 -->
            <xsl:call-template name="build-name-array">
                <xsl:with-param name="inputArray" select="array:remove($inputArray, 1)"/>
                <xsl:with-param name="currentArray" select="$updatedArray"/>
            </xsl:call-template>
        </xsl:if>
        
        <!-- 递归结束时返回最终数组 -->
        <xsl:if test="array:size($inputArray) = 0">
            <xsl:sequence select="$currentArray"/>
        </xsl:if>
    </xsl:template>
</xsl:stylesheet>

内容的提问来源于stack exchange,提问作者technocrat

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.10 11:59:58