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

如何在XSLT中迭代JSON数组并生成期望的JSON输出

XSLT处理JSON:拆分书籍条目并关联对应作者

输入JSON

{
    "publishers": [
        {
            "sellers": {
                "books": [
                    {
                        "test": {
                            "count": 1
                        },
                        "Name": "C",
                        "Type": "String"
                    },
                    {
                        "test": {
                            "count": 2
                        },
                        "Name": "C++",
                        "Type": "String"
                    }
                ],
                "Author": "Michel"
            }
        },
        {
            "sellers": {
                "books": [
                    {
                        "test": {
                            "count": 3
                        },
                        "Name": "Python",
                        "Type": "String"
                    },
                    {
                        "test": {
                            "count": 4
                        },
                        "Name": "Java",
                        "Type": "String"
                    }
                ],
                "Author": "Robert"
            }
        }
    ]
}

原XSLT样式表

<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
              version="4.0"
              xmlns:xs="http://www.w3.org/2001/XMLSchema"
              exclude-result-prefixes="#all">
              
              <xsl:output method="json" indent="yes"/>
            
               <xsl:template match="." name="xsl:initial-template">
                <xsl:sequence 
                  select="array { 
                            ?publishers?* ! map {
                              'resourceType' : 'Asset',
                              'indentifier' : map {'name' : array{?sellers?books?*?Name}},
                              'author' : map{'name' : ?sellers?Author}
                             
                            }
                          }"/>
              </xsl:template> 
              
            </xsl:stylesheet>

当前输出

[
              {
                "resourceType": "Asset",
                "author": { "name":"Michel" },
                "indentifier": { "name":[ "C", "C++" ] }
              },
              {
                "resourceType": "Asset",
                "author": { "name":"Robert" },
                "indentifier": { "name":[ "Python", "Java" ] }
              }
            ]

期望输出

[
                  {
                    "resourceType": "Asset",
                    "author": { "name":"Michel" },
                    "indentifier": { "name":"C" }
                  },
                  {
                    "resourceType": "Asset",
                    "author": { "name":"Michel" },
                    "indentifier": { "name":"C++" }
                  },
                  {
                    "resourceType": "Asset",
                    "author": { "name":"Robert" },
                    "indentifier": { "name":"Python" }
                  },
                  {
                    "resourceType": "Asset",
                    "author": { "name":"Robert" },
                    "indentifier": { "name":"Java" }
                  }
                ]

问题分析

原代码逻辑是遍历每个publisher并生成单个Asset对象,将该publisher下所有书籍名称打包为数组。但需求是每本书对应一个独立的Asset对象,同时关联所属作者信息。之前尝试用for-each构造报错,是因为XPath不支持XQuery的节点构造语法,需改用XPath的映射运算符!实现嵌套遍历。

修正后的XSLT代码

<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
              version="4.0"
              xmlns:xs="http://www.w3.org/2001/XMLSchema"
              exclude-result-prefixes="#all">
              
              <xsl:output method="json" indent="yes"/>
            
               <xsl:template match="." name="xsl:initial-template">
                <xsl:sequence 
                  select="array { 
                            ?publishers?* ! ?sellers ! let $author := ?Author return ?books?* ! map {
                              'resourceType' : 'Asset',
                              'indentifier' : map {'name' : ?Name},
                              'author' : map{'name' : $author}
                            }
                          }"/>
              </xsl:template> 
              
            </xsl:stylesheet>

代码解释

  1. 嵌套遍历逻辑:

    • 先遍历所有publisher:?publishers?*
    • 进入每个publisher的sellers节点:! ?sellers
    • 用let $author := ?Author保存当前sellers下的作者信息,供后续每本书复用
    • 遍历当前sellers下的所有books:! ?books?*
    • 为每本书生成独立的Asset对象,直接引用当前书籍的Name和预先保存的$author值
  2. 取消数组打包:
    原代码用array{?sellers?books?*?Name}将多本书名打包为数组,现在直接取单本书的?Name,确保每个Asset只对应一个书名。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.12 02:07:02