如何在 xslt 元素上应用 group by
Posted
技术标签:
【中文标题】如何在 xslt 元素上应用 group by【英文标题】:how to apply group by on xslt elements 【发布时间】:2011-01-09 22:31:53 【问题描述】:我需要根据某个属性对值进行分组并填充它。
下面提到的是 i/p xml,如果您看到用户有 4 行,对于 id 2,4 分区是相同的,即 HR
在生成实际的 o/p 时,我需要按部门分组...任何帮助???
I/P XML
<Users>
<User id="2" name="ABC" Division="HR"/>
<User id="3" name="xyz" Division="Admin"/>
<User id="4" name="LMN" Division="Payroll"/>
<User id="5" name="PQR" Division="HR"/>
</Users>
预期结果: 我需要根据 Division 对值进行分组并填充,即
<AllUsers>
<Division value="HR">
<User>
<id>2</id>
<name>ABC</name>
</User>
<User>
<id>5</id>
<name>PQR</name>
</User>
</Division>
<Division value="ADMIN">
<User>
<id>3</id>
<name>XYZ</name>
</User>
</Division>
<Division value="Payroll">
<User>
<id>4</id>
<name>LMN</name>
</User>
</Division>
</AllUsers>
【问题讨论】:
【参考方案1】:在 XSLT 1.0 中,使用 Muenchian 分组。
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" indent="yes" />
<xsl:key name="division" match="User" use="@Division" />
<xsl:template match="Users">
<AllUsers>
<xsl:apply-templates select="User[generate-id(.)=generate-id(key('division',@Division)[1])]"/>
</AllUsers>
</xsl:template>
<xsl:template match="User">
<Division value="@Division">
<xsl:for-each select="key('division', @Division)">
<User>
<id><xsl:value-of select="@id" /></id>
<name><xsl:value-of select="@name" /></name>
</User>
</xsl:for-each>
</Division>
</xsl:template>
</xsl:stylesheet>
在 XSLT 2.0 中,使用 xsl:foreach-group
<xsl:output method="xml" indent="yes" />
<xsl:template match="Users">
<AllUsers>
<xsl:for-each-group select="User" group-by="@Division">
<Division value="@Division">
<xsl:for-each select="current-group()">
<User>
<id><xsl:value-of select="@id" /></id>
<name><xsl:value-of select="@name" /></name>
</User>
</xsl:for-each>
</Division>
</xsl:for-each-group>
</AllUsers>
</xsl:template>
【讨论】:
如果可以的话,我会给这个+10,很好的例子:-) 在 XSLT 2.0 示例中,如果不使用 key() 函数,使用
<xsl:for-each-group select="*"
group-by="@Division">
....
</xsl:for-each-group>
看看这个例子:http://www.zvon.org/xxl/XSL-Ref/Tutorials/For-Each-Group/feg1.html
【讨论】:
【参考方案3】:我不喜欢添加这样的元素,这就是我要做的。这完美地工作。它提供了您需要的输出。试试看。
XML
<?xml version="1.0"?>
<Users>
<User id="2" name="ABC" Division="HR"/>
<User id="3" name="xyz" Division="Admin"/>
<User id="4" name="LMN" Division="Payroll"/>
<User id="5" name="PQR" Division="HR"/>
</Users>
XSLT 1.0
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
<xsl:output method="xml" indent="yes" />
<xsl:key name="division" match="User" use="@Division" />
<xsl:template match="Users">
<xsl:element name="AllUsers">
<xsl:apply-templates select="User[generate-id(.)=generate-id(key('division',@Division)[1])]" />
</xsl:element>
</xsl:template>
<xsl:template match="User">
<xsl:element name="Division">
<xsl:attribute name="value">
<xsl:value-of select="@Division" />
</xsl:attribute>
<xsl:for-each select="key('division', @Division)">
<xsl:element name="User">
<xsl:element name="id">
<xsl:value-of select="@id" />
</xsl:element>
<xsl:element name="name">
<xsl:value-of select="@name" />
</xsl:element>
</xsl:element>
</xsl:for-each>
</xsl:element>
</xsl:template>
</xsl:stylesheet>
XSLT 2.0
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="2.0">
<xsl:output method="xml" indent="yes" encoding="UTF-8" omit-xml-declaration="yes" />
<xsl:key name="division" match="User" use="@Division" />
<xsl:template match="Users">
<xsl:element name="AllUsers">
<xsl:for-each-group select="*" group-by="@Division">
<xsl:element name="Division">
<xsl:attribute name="value">
<xsl:value-of select="@Division" />
</xsl:attribute>
<xsl:for-each select="current-group()">
<xsl:element name="User">
<xsl:element name="id">
<xsl:value-of select="@id" />
</xsl:element>
<xsl:element name="name">
<xsl:value-of select="@name" />
</xsl:element>
</xsl:element>
</xsl:for-each>
</xsl:element>
</xsl:for-each-group>
</xsl:element>
</xsl:template>
</xsl:stylesheet>
使用任何一个都会给你这个输出,
<AllUsers>
<Division value="HR">
<User>
<id>2</id>
<name>ABC</name>
</User>
<User>
<id>5</id>
<name>PQR</name>
</User>
</Division>
<Division value="Admin">
<User>
<id>3</id>
<name>xyz</name>
</User>
</Division>
<Division value="Payroll">
<User>
<id>4</id>
<name>LMN</name>
</User>
</Division>
</AllUsers>
【讨论】:
XSLT 2 需要key
吗?以上是关于如何在 xslt 元素上应用 group by的主要内容,如果未能解决你的问题,请参考以下文章
XSLT Grouping's:将父级添加到子元素中的元素集
如何在 Apache Spark 中的 Group By Operation 形成的每个子集上应用用户定义函数?
如何在 pyspark 数据帧上应用 group by 并对结果对象进行转换
XSLT 1.0 - 如何将 2 个元素/兄弟元素组合成 1 个组