我必须在XML文档中对相同节点的子节目进行分组(合并)。 我找到了一个类似的主题,我得到了一些示例代码,但我的XML更复杂和扭曲,我需要真正理解以下XSL代码语法的逻辑:
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:key name="group-data" match="GroupData" use="concat(@ID, '___', @Key)" />
<xsl:template match="/">
<Groups>
<!--
Iterate over a node set containing just one GroupData element for
each combination of ID and Key
-->
<xsl:for-each select="/Groups/GroupData[count( . | key('group-data', concat(@ID, '___', @Key))[1]) = 1]">
<GroupData>
<!-- Copy attributes from the "prototype" GroupData -->
<xsl:copy-of select="@*"/>
<!--
Copy ItemData children from *all* GroupData elements with matching
ID/Key
-->
<xsl:copy-of select="key('group-data', concat(@ID, '___', @Key))/ItemData" />
</GroupData>
</xsl:for-each>
</Groups>
</xsl:template>
</xsl:stylesheet>
该XSL的示例 XML代码是:
<GroupData ID="xxx" Key="4" Temp="yyy">
<ItemData ID="zzz" Value="3"/>
</GroupData>
<GroupData ID="yyy" Key="4" Temp="yyy">
<ItemData ID="abc" Value="3"/>
</GroupData>
<GroupData ID="zzz" Temp="yyy">
<ItemData ID="pqr" Value="1982"/>
</GroupData>
<GroupData ID="zzz" Temp="yyy">
<ItemData ID="tuv" Value="1982"/>
</GroupData>
所以我想了解XSL代码,以便我可以将它应用于我的案例。
有人可以为我详细说明吗?更确切地说是这些部分:
<xsl:key name="group-data" match="GroupData" use="concat(@ID, '___', @Key)" />
和
<xsl:for-each select="/Groups/GroupData[count( . | key('group-data', concat(@ID, '___', @Key))[1]) = 1]">
<GroupData>
<!-- Copy attributes from the "prototype" GroupData -->
<xsl:copy-of select="@*"/>
<!--
Copy ItemData children from *all* GroupData elements with matching
ID/Key
-->
<xsl:copy-of select="key('group-data', concat(@ID, '___', @Key))/ItemData" />
</GroupData>
</xsl:for-each>
答案 0 :(得分:0)
<xsl:key name=""/>
使用指定的表达式作为查找键,在文档中创建XML节点的索引。这是为了更容易找到类似的节点。在XSL 1.x中,这是分组节点的主要方法。 key(name, key)
用于查询此索引。
在你的情况下
/Groups/GroupData[count( . | key('group-data', concat(@ID, '___', @Key))[1]) = 1]
基本上意味着:查找指定密钥索引中的第一个GroupData
个节点。这也可以写成:
/Groups/GroupData[generate-id() = generate-id(key('group-data', concat(@ID, '___', @Key))[1])]
generate-id()
方法为文档中的任何节点创建唯一ID。它可以比较节点的相等性。如果未提供参数,则使用活动节点(.
)