使用XSLT将平面XML结构更改为层次结构
问题描述:
我试图使用XSLT从平面XML文件创建分层XML文件,但不确定最佳方法是什么。使用XSLT将平面XML结构更改为层次结构
例如我需要
<root>
<inventory bag="1" fruit="apple"/>
<inventory bag="1" fruit="banana"/>
<inventory bag="2" fruit="apple"/>
<inventory bag="2" fruit="orange"/>
</root>
转换为
<inventory>
<baglist>
<bag id="1"/>
<bag id="2"/>
</baglist>
<bag id="1">
<fruit id="apple"/>
<fruit id="banana"/>
</bag>
<bag id="2">
<fruit id="apple"/>
<fruit id="orange"/>
</bag>
</inventory>
N个袋/水果
答
组inventory
元件基于它们bag
属性的值:
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:key name="byBag" match="root/inventory" use="@bag" />
<xsl:template match="/">
<inventory>
<baglist>
<xsl:apply-templates mode="baglist" />
</baglist>
<xsl:apply-templates />
</inventory>
</xsl:template>
<xsl:template
match="root/inventory[generate-id() =
generate-id(key('byBag', @bag)[1])]"
mode="baglist">
<bag id="{@bag}" />
</xsl:template>
<xsl:template
match="root/inventory[generate-id() =
generate-id(key('byBag', @bag)[1])]">
<bag id="{@bag}">
<xsl:apply-templates select="key('byBag', @bag)"
mode="details" />
</bag>
</xsl:template>
<xsl:template match="inventory" mode="details">
<fruit id="{@fruit}" />
</xsl:template>
</xsl:stylesheet>
谢谢,所以如果我明白这个正确,生成-ID()返回一个唯一的ID为当前节点,并且生成-ID (key(stuff)[1])用给定的bagid返回第一个节点的唯一标识符。这样,每个独特的bagid只有一个节点将与模板匹配。 – 2011-04-18 19:30:30
@N。岸 - 正是。然后,当我们将模板应用到'key('byBag',@bag)'时,我们指定一个'mode',这样我们就可以处理组中的所有项目,而无需重新匹配仅选择第一个项目的模板。这种技术被称为Muenchian方法进行分组。 – 2011-04-18 19:47:42
+1正确答案。 – 2011-04-18 20:44:38