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

如何在单个XSLT中实现JSON转XML及自定义XML格式转换

问题结论

完全可以在单个XSLT文件内完成JSON到目标XML格式的全流程转换,不需要拆分多步执行。
你之前合并失败的核心原因有三点:

  • 两段代码分别用了XSLT 1.0和3.0版本,混用时处理器进入兼容模式,无法正常对json-to-xml返回的临时节点树做XPath查询
  • 没有正确处理json-to-xml生成节点的命名空间,XPath选择节点时漏加前缀导致选不中目标节点
  • 用xsl:copy-of直接输出了中间解析结果,没有把解析结果存在变量中做后续转换。
实现方案

统一使用XSLT 3.0版本(json-to-xml是XPath 3.1标准函数,必须在3.0及以上版本的处理器中运行,比如Saxon 9.8+),直接将JSON解析结果存入变量,再对变量中的节点应用格式转换逻辑即可,不需要输出中间XML文件。

完整单文件样式表

<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" 
                xmlns:xs="http://www.w3.org/2001/XMLSchema"
                xmlns:f="http://www.w3.org/2005/xpath-functions"
                exclude-result-prefixes="xs f"
                version="3.0">
    <xsl:output indent="yes" encoding="UTF-8"/>

    <xsl:template match="/">
        <!-- 解析data标签内的JSON为通用XML结构,存入变量不输出 -->
        <xsl:variable name="parsed-json" select="json-to-xml(root/data)"/>
        <!-- 直接对解析结果应用格式转换,输出目标结构 -->
        <Distances>
            <xsl:for-each select="$parsed-json/f:map[@key='cities']/f:array">
                <Start>
                    <StartPoint><xsl:value-of select="@key"/></StartPoint>
                    <xsl:for-each select="f:map">
                        <Distance end="{f:string[@key='to']}" value="{f:number[@key='distance']}"/>
                    </xsl:for-each>
                </Start>
            </xsl:for-each>
        </Distances>
    </xsl:template>
</xsl:stylesheet>

逻辑复用写法

如果你想保留两段转换逻辑的独立性,方便后续维护,可以用xsl:apply-templates切换转换上下文,不需要用xsl:include/xsl:import引入外部文件:

<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" 
                xmlns:xs="http://www.w3.org/2001/XMLSchema"
                xmlns:f="http://www.w3.org/2005/xpath-functions"
                exclude-result-prefixes="xs f"
                version="3.0">
    <xsl:output indent="yes" encoding="UTF-8"/>

    <!-- 第一阶段逻辑:匹配输入,触发JSON解析 -->
    <xsl:template match="/">
        <xsl:variable name="parsed-json" select="json-to-xml(root/data)"/>
        <!-- 切换上下文到解析后的节点树,应用第二阶段转换模板 -->
        <xsl:apply-templates select="$parsed-json"/>
    </xsl:template>

    <!-- 第二阶段逻辑:匹配解析后的通用XML,输出目标格式 -->
    <xsl:template match="f:map">
        <Distances>
            <xsl:for-each select="f:map[@key='cities']/f:array">
                <Start>
                    <StartPoint><xsl:value-of select="@key"/></StartPoint>
                    <xsl:for-each select="f:map">
                        <Distance end="{f:string[@key='to']}" value="{f:number[@key='distance']}"/>
                    </xsl:for-each>
                </Start>
            </xsl:for-each>
        </Distances>
    </xsl:template>
</xsl:stylesheet>
注意事项
  • 所有json-to-xml生成的元素都属于http://www.w3.org/2005/xpath-functions命名空间,写XPath选择节点时必须绑定对应前缀,否则无法命中节点
  • 原第二阶段代码中取f:string和f:number时没有指定key属性,当JSON对象内有多个同类型字段时会取到第一个值,上述代码已经修正为按key选择对应字段,转换结果更稳定
  • 必须使用支持XSLT 3.0的处理器运行代码,低版本XSLT处理器不支持json-to-xml函数,也无法对临时节点树做模板匹配

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.01 15:51:38