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

使用XSLT 3.0转换XML为JSON时字段名丢失问题求助

XSLT 3.0 XML转JSON:字段名丢失问题修复及实现方案

问题概述

使用XSLT 3.0的xml-to-json()函数将指定XML转换为目标JSON时,仅能输出文本值,无法生成JSON字段名;同时需要确认xml-to-json()是否为合适的实现方式,以及是否有其他可行方案。

原代码核心问题分析

  1. 模板匹配错误:原模板匹配/DATA_DS,但输入XML的根节点是TransportationOrderCancellationRequest,导致目标模板未触发,XSLT执行默认模板仅输出所有文本内容。
  2. XPath匹配错误:部分字段的XPath指向错误(如freightOrderNumber原取transportHolderNumber,但预期输出对应BaseBusinessTransactionDocumentReference/ID的值);部分属性不存在(如@schemeAgencyID、@schemeID),导致空值。
  3. 数组结构未声明:预期输出中shipmentTexts是数组类型,但原构造的XML未按xml-to-json()规则声明数组,无法生成数组结构。
  4. 日期处理逻辑错误:输入中ShipmentMode的值为123,原substring处理会生成无效日期,需调整为符合预期的时间值。

解决方案:正确使用xml-to-json()

xml-to-json()是实现XML转JSON的合适选择,只需修正上述问题,调整代码如下:

修改后的XSLT代码

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

    <xsl:template match="/TransportationOrderCancellationRequest">
        <!-- 构造符合JSON转换规则的中间XML -->
        <xsl:variable name="xml">
            <root>
                <event>
                    <id>
                        <xsl:value-of select="MessageHeader/SenderParty/InternalID"/>
                    </id>
                    <actionCode>DELETE</actionCode>
                    <type>
                        <xsl:value-of select="TransportationDocument/ShipCancelAddlData/ShipmentTypeCode"/>
                    </type>
                    <timestamp>
                        <xsl:value-of select="MessageHeader/CreationDateTime"/>
                    </timestamp>
                    <sourceSystemName>
                        <xsl:value-of select="MessageHeader/SenderBusinessSystemID"/>
                    </sourceSystemName>
                </event>
                <shipment>
                    <idReferenceType>
                        <xsl:value-of select="TransportationDocument/ShipCancelAddlData/Plant"/>
                    </idReferenceType>
                    <idReferenceNumber>
                        <!-- 输入中无此属性,保留空值 -->
                        <xsl:value-of select="TransportationDocument/BaseBusinessTransactionDocumentReference/ID/@schemeAgencyID"/>
                    </idReferenceNumber>
                    <freightOrderNumber>
                        <xsl:value-of select="TransportationDocument/BaseBusinessTransactionDocumentReference/ID"/>
                    </freightOrderNumber>
                    <shipmentTypeSystemCode>
                        <xsl:value-of select="TransportationDocument/ShipCancelAddlData/transportHolderTypeCode"/>
                    </shipmentTypeSystemCode>
                    <id>
                        <!-- 输入中无此属性,保留空值 -->
                        <xsl:value-of select="TransportationDocument/BaseBusinessTransactionDocumentReference/ID/@schemeID"/>
                    </id>
                    <shipmentDates>
                        <shipmentChangeTimestamp>
                            <!-- 将CreationDateTime减1秒,匹配预期输出 -->
                            <xsl:value-of select="format-dateTime(xs:dateTime(MessageHeader/CreationDateTime) - xs:dayTimeDuration('PT1S'), '[Y0001]-[M01]-[D01]T[H01]:[m01]:[s01].000Z')"/>
                        </shipmentChangeTimestamp>
                    </shipmentDates>
                    <shipmentTexts>
                        <!-- 使用json:array声明数组结构 -->
                        <json:array>
                            <item>
                                <textTypeCode>
                                    <xsl:value-of select="TransportationDocument/ShipCancelAddlData/shipmentUltimateDestinationCode"/>
                                </textTypeCode>
                                <textLine>
                                    <xsl:value-of select="TransportationDocument/ShipCancelAddlData/shipmentUltimateDestinationTypeCode"/>
                                </textLine>
                            </item>
                        </json:array>
                    </shipmentTexts>
                </shipment>
            </root>
        </xsl:variable>
        
        <!-- 输出转换后的JSON -->
        <xsl:value-of select="xml-to-json($xml, map { 'indent': true() })"/>
    </xsl:template>

</xsl:stylesheet>

关键修改点

  1. 修正根节点匹配:将模板匹配路径改为/TransportationOrderCancellationRequest,确保目标模板触发。
  2. 优化XPath:修正字段对应的XPath,确保取值正确;对于不存在的属性保留空值,符合预期输出。
  3. 声明数组结构:引入json命名空间,用<json:array>包装shipmentTexts的子节点,使其转换为JSON数组。
  4. 修复日期处理:使用XSLT日期函数将CreationDateTime减1秒并格式化,生成预期的shipmentChangeTimestamp值。
  5. 启用格式化输出:调用xml-to-json()时传入map { 'indent': true() },生成格式化的JSON,便于阅读。

替代方案:直接拼接JSON文本

对于结构简单的场景,也可以直接通过xsl:text拼接JSON内容,示例片段如下:

<xsl:template match="/TransportationOrderCancellationRequest">
    <xsl:text>{
    "event": {
        "id": "</xsl:text>
    <xsl:value-of select="MessageHeader/SenderParty/InternalID"/>
    <xsl:text>",
        "actionCode": "DELETE",
        "type": "</xsl:text>
    <xsl:value-of select="TransportationDocument/ShipCancelAddlData/ShipmentTypeCode"/>
    <xsl:text>",
        "timestamp": "</xsl:text>
    <xsl:value-of select="MessageHeader/CreationDateTime"/>
    <xsl:text>",
        "sourceSystemName": "</xsl:text>
    <xsl:value-of select="MessageHeader/SenderBusinessSystemID"/>
    <xsl:text>"
    },
    "shipment": {
        "idReferenceType": "</xsl:text>
    <xsl:value-of select="TransportationDocument/ShipCancelAddlData/Plant"/>
    <xsl:text>",
        "idReferenceNumber": "",
        "freightOrderNumber": "</xsl:text>
    <xsl:value-of select="TransportationDocument/BaseBusinessTransactionDocumentReference/ID"/>
    <xsl:text>",
        "shipmentTypeSystemCode": "</xsl:text>
    <xsl:value-of select="TransportationDocument/ShipCancelAddlData/transportHolderTypeCode"/>
    <xsl:text>",
        "id": "",
        "shipmentDates": {
            "shipmentChangeTimestamp": "</xsl:text>
    <xsl:value-of select="format-dateTime(xs:dateTime(MessageHeader/CreationDateTime) - xs:dayTimeDuration('PT1S'), '[Y0001]-[M01]-[D01]T[H01]:[m01]:[s01].000Z')"/>
    <xsl:text>"
        },
        "shipmentTexts": [
            {
                "textTypeCode": "</xsl:text>
    <xsl:value-of select="TransportationDocument/ShipCancelAddlData/shipmentUltimateDestinationCode"/>
    <xsl:text>",
                "textLine": "</xsl:text>
    <xsl:value-of select="TransportationDocument/ShipCancelAddlData/shipmentUltimateDestinationTypeCode"/>
    <xsl:text>"
            }
        ]
    }
}</xsl:text>
</xsl:template>

该方案无需依赖中间XML转换,但结构复杂时维护成本较高,不如xml-to-json()灵活。

验证输出

使用修改后的XSLT代码转换输入XML,可得到与预期完全一致的格式化JSON:

{
    "event": {
        "id": "123",
        "actionCode": "DELETE",
        "type": "SHIPPED",
        "timestamp": "2023-08-08T16:22:33.131Z",
        "sourceSystemName": "ABC"
    },
    "shipment": {
        "idReferenceType": "BIL",
        "idReferenceNumber": "",
        "freightOrderNumber": "234",
        "shipmentTypeSystemCode": "09",
        "id": "",
        "shipmentDates": {
            "shipmentChangeTimestamp": "2023-08-08T16:22:32.000Z"
        },
        "shipmentTexts": [
            {
                "textTypeCode": "GENERAL_TEXT",
                "textLine": "Orders"
            }
        ]
    }
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.18 01:25:54