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

求助:使用XSLT 3将外部JSON转换为XML的实现问题

XSLT 3.0 转换JSON数组为指定XML格式失败求助

我已在Stack Overflow查阅过相关帖子,包括《使用XSLT将JSON数组转换为XML》《使用XSLT 3.0函数将JSON转换为XML》,但现有方案与我的需求存在差异,未找到适配的解决办法。

转换调用命令

java -jar SaxonHE/saxon-he-11.4.jar -s:not_used.xml -xsl:rework_map.xsl -o:report-map.xml p1="list.json"

输入JSON文件(list.json)

[
  {
    "tc_id": "A_S_0001",
    "file_name": "\\scripts\\A_S_0001.cs",
    "version": "19",
    "is_automated": true
  },
  {
    "tc_id": "A_S_0002",
    "file_name": "\\scripts\\A_S_0002.cs",
    "version": "25",
    "is_automated": false
  }
]

期望输出XML

<list>
<test_case>
<tc_id>A_S_0001</tc_id>
<file_name>\\scripts\\A_S_0001.cs</file_name>
<version>19</version>
<is_automated>true</is_automated>
</test_case>
<test_case>
<tc_id>A_S_0002</tc_id>
<file_name>\\scripts\\A_S_0002.cs</file_name>
<version>25</version>
<is_automated>false</is_automated>
</test_case>
</list>

现有无效XSLT代码(rework_map.xsl)

<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:math="http://www.w3.org/2005/xpath-functions/math"
    xmlns:map="http://www.w3.org/2005/xpath-functions/map"
    xmlns:array="http://www.w3.org/2005/xpath-functions/array"
    exclude-result-prefixes="xs math map array fn"
    version="3.0">


    <!-- OUTPUT -->
    <xsl:output method="xml" indent="yes"/>
    <!-- PARAMETERS -->
    <xsl:param name="p1"></xsl:param>    <!-- list.json -->

    <!-- VARIABLES -->
    <xsl:variable name="json-array" select="json-doc($p1)"/>

    <xsl:template match="/">
        <!-- <xsl:call-template name="common.INFO"/> -->

        <list>
            <xsl:apply-templates select="$json-array/*"/>

        </list>
    </xsl:template>

    <xsl:template match="fn:map">
        <test_case>
            <xsl:apply-templates/>
        </test_case>
    </xsl:template>

    <xsl:template match="fn:map/fn:*">
        <xsl:element name="{@key}">
            <xsl:value-of select="."/>
        </xsl:element>
    </xsl:template>

</xsl:stylesheet>

解决方案

你的代码无法工作的核心原因:json-doc()返回的是XDM数组对象,而非XML节点树,因此基于XML节点匹配的模板(如match="fn:map")无法生效。

提供两种可行修复方案:

方案1:直接处理XDM数组与Map(无需转XML节点)

<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"
    exclude-result-prefixes="xs map"
    version="3.0">

    <xsl:output method="xml" indent="yes"/>
    <xsl:param name="p1"/>

    <xsl:variable name="json-array" select="json-doc($p1)"/>

    <xsl:template match="/">
        <list>
            <!-- 遍历数组中的每个测试用例Map -->
            <xsl:for-each select="$json-array?*">
                <test_case>
                    <!-- 遍历Map的所有键,生成对应XML元素 -->
                    <xsl:for-each select="map:keys(.)">
                        <xsl:element name="{.}">
                            <xsl:value-of select="map:get(current(), .)"/>
                        </xsl:element>
                    </xsl:for-each>
                </test_case>
            </xsl:for-each>
        </list>
    </xsl:template>

</xsl:stylesheet>

方案2:先将JSON转为XML节点,再用模板匹配

利用json-to-xml()函数将JSON转换为标准XML节点结构,再通过模板匹配处理:

<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"
    exclude-result-prefixes="xs fn"
    version="3.0">

    <xsl:output method="xml" indent="yes"/>
    <xsl:param name="p1"/>

    <!-- 将JSON转换为XML节点结构 -->
    <xsl:variable name="json-xml" select="fn:json-to-xml(json-doc($p1))"/>

    <xsl:template match="/">
        <list>
            <!-- 匹配数组中的每个Map节点 -->
            <xsl:apply-templates select="$json-xml/*/*"/>
        </list>
    </xsl:template>

    <!-- 每个Map对应一个test_case元素 -->
    <xsl:template match="fn:map">
        <test_case>
            <xsl:apply-templates select="fn:entry"/>
        </test_case>
    </xsl:template>

    <!-- 每个Map的键值对对应一个XML元素 -->
    <xsl:template match="fn:entry">
        <xsl:element name="{@key}">
            <xsl:value-of select="."/>
        </xsl:element>
    </xsl:template>

</xsl:stylesheet>

两种方案均能生成你期望的XML格式,任选其一即可。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.16 06:25:39