使用XSLT移除XML多根节点的技术实现问题
解决XSLT转换XML到JSON时移除外层根节点的问题
看起来你已经离目标只差一步了!问题出在默认的XML转JSON逻辑会完整保留原XML的层级结构,把根节点和它的子节点包装成外层JSON对象。要直接输出Part元素的数组,我们可以用XSLT 3.0的原生JSON构造功能来精准控制输出格式。
最优解决方案:XSLT 3.0代码
下面的样式表会直接将XML中的Part元素序列转换为你期望的JSON数组:
<xsl:stylesheet version="3.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:ns1="urn:za.xxxxxxxx.com:supplychain:3rdp:transdata" exclude-result-prefixes="ns1"> <!-- 指定输出为格式化的JSON --> <xsl:output method="json" indent="yes"/> <xsl:template match="/"> <!-- 构造JSON数组:遍历每个Part元素,将其转为JSON对象 --> <xsl:sequence select="array { /*:DDMRP_Parts/Part ! map { 'PartNumber': string(PartNumber), 'Location': string(Location), 'Description': string(Description), 'UnitOfMeasure': string(UnitOfMeasure), 'PartType': string(PartType), 'FixedLeadTime': string(FixedLeadTime), 'MaterialType': string(MaterialType) } }"/> </xsl:template> </xsl:stylesheet>
代码细节说明
- 命名空间兼容:我们声明了输入XML中的
ns1命名空间,并用/*:DDMRP_Parts匹配任意命名空间下的根节点,避免因前缀变化导致匹配失败。 - 精准JSON构造:
array { ... }直接创建JSON数组结构!运算符遍历每个Part元素map { ... }将每个Part的子元素映射为JSON键值对,用string()确保值是标准字符串类型
- 输出格式控制:
xsl:output method="json"确保输出为标准JSON格式,indent="yes"让结果更易读。
为什么之前的输出有外层结构?
默认的XML转JSON工具(比如XSLT的xml-to-json函数)会严格按照XML层级生成JSON:根节点ns1:DDMRP_Parts会成为JSON的顶级键,它的子元素Part会成为该键对应的数组。而我们的代码跳过了根节点层级,直接将Part元素序列转为数组,就得到了你想要的结果。
兼容XSLT 2.0的备选方案
如果你只能使用XSLT 2.0,可以通过手动拼接JSON字符串实现(虽然不如3.0优雅):
<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:ns1="urn:za.xxxxxxxx.com:supplychain:3rdp:transdata" exclude-result-prefixes="ns1"> <xsl:output method="text" encoding="UTF-8"/> <xsl:template match="/"> <xsl:text>[</xsl:text> <xsl:for-each select="/*:DDMRP_Parts/Part"> <xsl:if test="position() > 1">,</xsl:if> <xsl:text>{ "PartNumber" : "</xsl:text> <xsl:value-of select="PartNumber"/> <xsl:text>", "Location" : "</xsl:text> <xsl:value-of select="Location"/> <xsl:text>", "Description" : "</xsl:text> <xsl:value-of select="Description"/> <xsl:text>", "UnitOfMeasure" : "</xsl:text> <xsl:value-of select="UnitOfMeasure"/> <xsl:text>", "PartType" : "</xsl:text> <xsl:value-of select="PartType"/> <xsl:text>", "FixedLeadTime" : "</xsl:text> <xsl:value-of select="FixedLeadTime"/> <xsl:text>", "MaterialType" : "</xsl:text> <xsl:value-of select="MaterialType"/> <xsl:text>" }</xsl:text> </xsl:for-each> <xsl:text>]</xsl:text> </xsl:template> </xsl:stylesheet>
这个2.0版本通过拼接文本的方式生成JSON数组,注意如果你的数据里包含引号或反斜杠,需要额外添加转义逻辑。
内容的提问来源于stack exchange,提问作者Luvuyo
相关产品推荐
相关产品推荐

