请求将扁平XML转换为层级结构的XSLT实现方案
需求:将扁平结构XML转换为层级结构的XSLT实现
需要编写XSLT代码完成以下转换:
- 源XML为扁平结构,包含多组
Header节点,每组Header后跟随与其关联的Item节点,关联关系仅由出现顺序决定 - 目标XML需将每组
Header对应的所有Item节点嵌套到该Header节点内部
源XML示例
<?xml version="1.0" encoding="UTF-8"?> <ns0:FlatInfo xmlns:ns0="http://mynamespace.com"> <Header> <OrderNo>100</OrderNo> </Header> <Item> <ItemNo>1</ItemNo> <Product>Slime</Product> <Quantity>2</Quantity> </Item> <Item> <ItemNo>2</ItemNo> <Product>Gunge</Product> <Quantity>4</Quantity> </Item> <Header> <OrderNo>102</OrderNo> </Header> <Item> <ItemNo>1</ItemNo> <Product>Sludge</Product> <Quantity>55</Quantity> </Item> </ns0:FlatInfo>
目标XML示例
<?xml version="1.0" encoding="UTF-8"?> <ns0:TreeInfo xmlns:ns0="http://mynamespace.com"> <Header> <OrderNo>100</OrderNo> <Item> <ItemNo>1</ItemNo> <Product>Slime</Product> <Quantity>2</Quantity> </Item> <Item> <ItemNo>2</ItemNo> <Product>Gunge</Product> <Quantity>4</Quantity> </Item> </Header> <Header> <OrderNo>102</OrderNo> <Item> <ItemNo>1</ItemNo> <Product>Sludge</Product> <Quantity>55</Quantity> </Item> </Header> </ns0:TreeInfo>
解决方案:XSLT代码
<?xml version="1.0" encoding="UTF-8"?> <xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:ns0="http://mynamespace.com"> <!-- 默认模板:复制所有节点和属性,保留无需修改的内容 --> <xsl:template match="@*|node()"> <xsl:copy> <xsl:apply-templates select="@*|node()"/> </xsl:copy> </xsl:template> <!-- 替换根节点名称,仅处理Header节点 --> <xsl:template match="ns0:FlatInfo"> <ns0:TreeInfo> <xsl:apply-templates select="Header"/> </ns0:TreeInfo> </xsl:template> <!-- 处理Header节点,嵌套关联的Item --> <xsl:template match="Header"> <xsl:copy> <!-- 复制Header内部的所有内容 --> <xsl:apply-templates select="@*|node()"/> <!-- 筛选当前Header之后、下一个Header之前的所有Item节点 --> <xsl:apply-templates select="following-sibling::Item[preceding-sibling::Header[1] = current()]"/> </xsl:copy> </xsl:template> <!-- 空模板:避免Item节点被默认模板重复输出 --> <xsl:template match="Item"/> </xsl:stylesheet>
代码说明
- 默认模板:负责复制所有节点和属性,确保原有内容中无需修改的部分原样保留
- 根节点模板:将源XML的根节点
ns0:FlatInfo替换为目标根节点ns0:TreeInfo,并指定只处理Header节点 - Header模板:
- 复制当前
Header的全部内容 - 通过
following-sibling::Item[preceding-sibling::Header[1] = current()]精准筛选出属于当前Header的关联Item,并将它们嵌套到Header内部
- 复制当前
- Item模板:设置为空模板,避免
Item节点被默认模板重复输出
内容的提问来源于stack exchange,提问作者Trickster__
相关产品推荐
相关产品推荐

