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

如何解决Workday报告XSLT转JSON的序列处理错误?

解决XSLT JSON输出错误:无法处理多个项的序列

我基于Workday XML报告数据开发了通用XSLT转换程序(无硬编码列),设置output method="text"时程序可正常运行,但改为json时触发错误:Error executing XSLT at line 8 : JSON output method cannot handle sequences of two or more items,目标是生成符合预期格式的JSON数据。


XML数据

<wd:Report_Data xmlns:wd="urn:com.workday.report/EntryReason">
<wd:Report_Entry>
<wd:EntryReasonRefID>ABC_123</wd:EntryReasonRefID>
<wd:EntryReason>ABC_123 Reimbursement - Non Taxable</wd:EntryReason>
<wd:CreatedMoment>2022-08-30T18:35:34.040-07:00</wd:CreatedMoment>
<wd:LastFunctionallyUpdated>2022-09-01T12:37:48.427-07:00</wd:LastFunctionallyUpdated>
</wd:Report_Entry>
<wd:Report_Entry>
<wd:EntryReasonRefID>ABC_456</wd:EntryReasonRefID>
<wd:EntryReason>ABC_456 - Air Travel</wd:EntryReason>
<wd:CreatedMoment>2022-08-30T18:35:34.370-07:00</wd:CreatedMoment>
<wd:LastFunctionallyUpdated>2022-09-01T12:37:48.552-07:00</wd:LastFunctionallyUpdated>
</wd:Report_Entry>
<wd:Report_Entry>
<wd:EntryReasonRefID>ABC_789</wd:EntryReasonRefID>
<wd:EntryReason>ABC_789 - Car Rental</wd:EntryReason>
<wd:CreatedMoment>2022-08-30T18:35:34.501-07:00</wd:CreatedMoment>
<wd:LastFunctionallyUpdated>2022-09-01T12:37:48.672-07:00</wd:LastFunctionallyUpdated>
</wd:Report_Entry>
<wd:Report_Entry>
<wd:EntryReasonRefID>ABC_999</wd:EntryReasonRefID>
<wd:EntryReason>ABC_999 - Hotel</wd:EntryReason>
<wd:EntryReason>ABC_999 - Rental</wd:EntryReason>
<wd:CreatedMoment>2022-08-30T18:35:34.636-07:00</wd:CreatedMoment>
<wd:LastFunctionallyUpdated>2022-09-01T12:37:48.779-07:00</wd:LastFunctionallyUpdated>
</wd:Report_Entry>
</wd:Report_Data>

原XSLT代码

<xsl:stylesheet
    xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
    xmlns:wd="urn:com.workday.report/EntryReason" version="3.0">
     <xsl:output method="json" indent="yes"/>
    <xsl:template match="/wd:Report_Data">
    <xsl:text>&#xA0;[&#xa;</xsl:text>
        <xsl:for-each select="wd:Report_Entry">
            <xsl:text>&#xA0;{&#xa;</xsl:text>
            
            <xsl:for-each select="./*"> 
                <xsl:text>&#xA0;</xsl:text>
                <xsl:choose> 
                    <xsl:when test="@wd:Descriptor"><xsl:value-of select="concat('&quot;',local-name(),'&quot;:&quot;',@wd:Descriptor,'&quot;')"/></xsl:when>
                    <xsl:otherwise><xsl:value-of select="concat('&quot;',local-name(),'&quot;:&quot;',.,'&quot;')"/></xsl:otherwise>
                </xsl:choose>
                <xsl:if test="position() != last()">
                    <xsl:text>,&#xa; </xsl:text>
                </xsl:if>
            </xsl:for-each>
             
            <xsl:text>&#xa; &#xA0;}</xsl:text>
            <xsl:if test="position() != last()">
                <xsl:text>,&#xa;</xsl:text>
            </xsl:if>
        </xsl:for-each>
        
        <xsl:text>&#xa;&#xA0;]</xsl:text>
    </xsl:template>
    <xsl:template match="node() | @*"/>
</xsl:stylesheet>

错误详情

Error executing XSLT at line 8 : JSON output method cannot handle sequences of two or more items


预期输出

[
    {
        "EntryReasonRefID": "ABC_123",
        "EntryReason": "ABC_123 Reimbursement - Non Taxable",
        "CreatedMoment": "2022-08-30T18:35:34.040-07:00",
        "LastFunctionallyUpdated": "2022-09-01T12:37:48.427-07:00"
    },
    {
        "EntryReasonRefID": "ABC_456",
        "EntryReason": "ABC_456 - Air Travel",
        "CreatedMoment": "2022-08-30T18:35:34.370-07:00",
        "LastFunctionallyUpdated": "2022-09-01T12:37:48.552-07:00"
    },
    {
        "EntryReasonRefID": "ABC_789",
        "EntryReason": "ABC_789 - Car Rental",
        "CreatedMoment": "2022-08-30T18:35:34.501-07:00",
        "LastFunctionallyUpdated": "2022-09-01T12:37:48.672-07:00"
    },
    {
        "EntryReasonRefID": "ABC_999",
        "EntryReason": "ABC_999 - Hotel; ABC_999 - Rental",
        "CreatedMoment": "2022-08-30T18:35:34.636-07:00",
        "LastFunctionallyUpdated": "2022-09-01T12:37:48.779-07:00"
    }
]

(注:修正了原预期输出中EntryReasonRefID与EntryReason的对应错误,使其匹配XML数据逻辑)


解决方案

错误原因

当使用method="json"时,XSLT处理器要求输出单个JSON值节点(数组或对象),但原代码通过拼接多个文本节点生成JSON结构,导致输出的是多节点序列,不符合JSON输出方法的规范,因此触发错误。

修改后的XSLT代码

<xsl:stylesheet
    xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
    xmlns:wd="urn:com.workday.report/EntryReason"
    xmlns:map="http://www.w3.org/2005/xpath-functions/map"
    version="3.0">
    <xsl:output method="json" indent="yes"/>

    <xsl:template match="/wd:Report_Data">
        <!-- 构造JSON数组,每个元素为Report_Entry对应的对象 -->
        <xsl:sequence select="array{
            for $entry in wd:Report_Entry
            return map:merge(
                for $group in $entry/* group by $name := local-name()
                return map {
                    $name : if (count($group) > 1) then string-join($group, '; ') else string($group)
                }
            )
        }"/>
    </xsl:template>

    <xsl:template match="node() | @*"/>
</xsl:stylesheet>

代码说明

  1. 数组构造:用array{}直接生成JSON数组,遍历每个wd:Report_Entry作为数组元素。
  2. 重复节点合并:通过group by local-name()对每个Report_Entry的子节点按名称分组,若同一名称存在多个节点(如第四个Entry的两个EntryReason),则用string-join将值用分号拼接;否则直接取节点文本值。
  3. Map转换:每个分组转为键值对map,再通过map:merge合并成单个对象map,最终组成数组元素。

该代码生成的输出是单个JSON数组节点,符合method="json"的要求,同时自动处理了重复字段的合并,完全匹配预期格式。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.26 23:12:36