如何使用XSLT动态将嵌套XML转换为扁平化XML?
动态扁平化嵌套XML的XSLT解决方案
我来帮你写一个通用的XSLT,它不需要硬编码任何节点名称,能自动处理任意结构的嵌套节点,把嵌套的子节点转换为「父节点名.子节点名」的形式,同时保留顶层的重复节点(比如示例中的Account)。
通用XSLT代码
<?xml version="1.0" encoding="UTF-8"?> <xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> <!-- 默认模板:复制所有文本节点和属性,确保内容不丢失 --> <xsl:template match="text()|@*"> <xsl:copy/> </xsl:template> <!-- 处理包含子元素的顶层父节点(比如Account、queryResponse),保留节点本身,处理内部子节点 --> <xsl:template match="*[*]"> <xsl:copy> <xsl:apply-templates select="node()"/> </xsl:copy> </xsl:template> <!-- 处理中间嵌套节点(比如RecordType):不复制节点本身,而是将其子节点带上前缀后输出 --> <xsl:template match="*[* and parent::*[*]]"> <xsl:apply-templates select="*"> <xsl:with-param name="prefix" select="name()"/> </xsl:apply-templates> </xsl:template> <!-- 处理叶子节点:如果有前缀就拼接成「前缀.节点名」的形式,否则直接输出原节点 --> <xsl:template match="*[not(*)]"> <xsl:param name="prefix" select="''"/> <xsl:element name="{concat($prefix, if ($prefix != '') then '.' else '', name())}"> <xsl:apply-templates select="@*|node()"/> </xsl:element> </xsl:template> </xsl:stylesheet>
代码说明
- 默认模板:负责复制所有文本内容和属性,保证原始的文本值和属性不会丢失。
- 顶层父节点处理:比如示例中的
queryResponse和Account,会保留它们的节点结构,然后递归处理内部的子节点。 - 中间嵌套节点处理:比如
RecordType这种包含子元素的中间节点,不会被复制到输出中,而是把它的子节点传递给下一个模板,并带上当前节点的名称作为前缀。 - 叶子节点处理:最终的叶子节点(没有子元素的节点)会根据传入的前缀拼接新的节点名称,比如
Id加上前缀RecordType就变成RecordType.Id。
效果验证
用你提供的示例输入XML运行这个XSLT,会得到和你期望完全一致的输出:
Account节点被完整保留RecordType节点被移除,它的子节点变成RecordType.Id和RecordType.DeveloperName直接放在Account内部- 所有原始的叶子节点(
Id、Name、RecordTypeId)保持原样
这个XSLT是完全通用的,不管你的输入XML节点名称怎么变化,只要是嵌套结构,都能自动进行扁平化处理。
内容的提问来源于stack exchange,提问作者saravana perumal Raj
相关产品推荐
相关产品推荐

