如何在SAP CPI中用XSLT将XML转为含单元素数组的JSON?
解决SAP CPI中XSLT转换XML到JSON时单条记录强制生成数组的问题
要解决单条记录也生成数组的问题,核心是强制指定需要数组化的节点,不依赖节点数量自动判断,以下是针对两种常见XSLT转JSON方式的解决方案:
场景1:使用JSONX格式转换(SAP CPI常用方式)
如果你的现有XSLT是基于JSONX(http://www.ibm.com/xmlns/prod/2009/jsonx)规范编写,只需修改模板逻辑,直接用json:array标签包裹目标节点的所有子记录:
修改后的XSLT代码
<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:json="http://www.ibm.com/xmlns/prod/2009/jsonx"> <xsl:template match="/"> <json:object> <xsl:apply-templates select="Root"/> </json:object> </xsl:template> <xsl:template match="Root"> <json:object name="Root"> <!-- 强制用数组包裹Item节点,无论数量多少 --> <json:array name="Item"> <xsl:apply-templates select="Item"/> </json:array> </json:object> </xsl:template> <xsl:template match="Item"> <json:object> <json:string name="ID"><xsl:value-of select="ID"/></json:string> <json:string name="Name"><xsl:value-of select="Name"/></json:string> </json:object> </xsl:template> </xsl:stylesheet>
关键修改点
- 在父节点(如
Root)的模板中,用<json:array name="Item">直接包裹所有Item节点的处理逻辑,不管Item是1条还是多条,都会被封装为数组 - 子节点(
Item)的模板中去掉name="Item"属性,因为数组名称已经在json:array标签上定义,数组内只保留纯对象结构
场景2:使用XSLT 3.0原生xml-to-json()函数
如果你的CPI环境支持XSLT 3.0,可通过在中间XML结构中添加json:array="true"属性,告诉转换函数强制生成数组:
修改后的XSLT代码
<xsl:stylesheet version="3.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:json="http://www.w3.org/2005/xpath-functions"> <xsl:output method="json" indent="yes"/> <xsl:template match="/"> <xsl:variable name="structured-xml"> <Root> <!-- 标记Item节点为数组类型 --> <Item json:array="true"> <xsl:for-each select="Root/Item"> <item> <ID><xsl:value-of select="ID"/></ID> <Name><xsl:value-of select="Name"/></Name> </item> </xsl:for-each> </Item> </Root> </xsl:variable> <xsl:value-of select="xml-to-json($structured-xml, map{'indent':true()})"/> </xsl:template> </xsl:stylesheet>
原理说明
json:array="true"属性是XSLT 3.0 XML转JSON的标准标记,只要添加这个属性,无论子节点数量是1还是N,都会被序列化为数组结构。
验证效果
以单条记录的原XML为例:
<Root> <Item> <ID>1</ID> <Name>Test Product</Name> </Item> </Root>
转换后会生成符合要求的JSON:
{ "Root": { "Item": [ { "ID": "1", "Name": "Test Product" } ] } }
内容的提问来源于stack exchange,提问作者megrao1811
相关产品推荐
相关产品推荐

