按 Xsl 中子节点的值对 xml 节点进行分组
<root>
<element>
<id>1</id>
<group>first</group>
</element>
<element>
<id>2</id>
<group>second</group>
</element>
<element>
<id>3</id>
<group>first</group>
</element>
...
<root>
如何在 xslt 1.0 中按组名对元素进行分组.输出:
How I can group my elements by the group name in xslt 1.0. the output:
<root>
<group name="first">
<element>
<id>1</id>
<group>first</group>
</element>
<element>
<id>3</id>
<group>first</group>
</element>
</group>
<group name="second">
<element>
<id>2</id>
<group>second</group>
</element>
</group>
</root>
有什么想法吗?
这是 Muenchian Grouping 的工作.您将在 StackOverflow 上的 XSLT 标记中找到大量示例.
This is a job for Muenchian Grouping. You will numerous examples of it within the XSLT tag here on StackOverflow.
首先,您需要定义一个键来帮助您对组进行分组
First, you need to define a key to help you group the groups
<xsl:key name="groups" match="group" use="."/>
这将查找给定组名的 group 元素.
This will look up group elements for a given group name.
接下来,您需要匹配每个差异组名称的第一个实例的所有匹配项.这是通过这个看起来很可怕的声明完成的
Next, you need to match all the occurrences of the first instance of each distince group name. This is done with this scary looking statement
<xsl:apply-templates select="element/group[generate-id() = generate-id(key('groups', .)[1])]"/>
即匹配在我们的键中第一次出现该元素的组元素.
i.e Match group elements which happen to be the first occurence of that element in our key.
当您匹配了不同的组节点后,您可以遍历所有其他同名的组节点(其中 $currentGroup 是保存当前组名的变量)
When you have matched the distinct group nodes, you can then loop through all other group nodes with the same name (where $currentGroup is a variable holding the current group name)
<xsl:for-each select="key('groups', $currentGroup)">
把这个放在一起给出
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:key name="groups" match="group" use="."/>
<xsl:template match="/root">
<root>
<xsl:apply-templates select="element/group[generate-id() = generate-id(key('groups', .)[1])]"/>
</root>
</xsl:template>
<xsl:template match="group">
<xsl:variable name="currentGroup" select="."/>
<group>
<xsl:attribute name="name">
<xsl:value-of select="$currentGroup"/>
</xsl:attribute>
<xsl:for-each select="key('groups', $currentGroup)">
<element>
<id>
<xsl:value-of select="../id"/>
</id>
<name>
<xsl:value-of select="$currentGroup"/>
</name>
</element>
</xsl:for-each>
</group>
</xsl:template>
</xsl:stylesheet>
将其应用于您的示例 XML 会得到以下结果
Applying this on your sample XML gives the following result
<root>
<group name="first">
<element>
<id>1</id>
<name>first</name>
</element>
<element>
<id>3</id>
<name>first</name>
</element>
</group>
<group name="seccond">
<element>
<id>2</id>
<name>seccond</name>
</element>
</group>
</root>