如何用XSLT 1.0按x、y值分组point节点并统计数量?
问题描述
给定输入XML:
<Points> <point> <x>10</x> <y>20</y> <z>30</z> </point> <point> <x>30</x> <y>20</y> <z>10</z> </point> <point> <x>20</x> <y>10</y> <z>10</z> </point> <point> <x>10</x> <y>20</y> <z>40</z> </point> <point> <x>10</x> <y>10</y> <z>10</z> </point> <point> <x>30</x> <y>20</y> <z>10</z> </point> <point> <x>30</x> <y>20</y> <z>10</z> </point> </Points>
期望输出XML:
<Details> <Point2D> <x>10</x> <y>20</y> <count>2</count> </Point2D> <Point2D> <x>30</x> <y>20</y> <count>3</count> </Point2D> <Point2D> <x>20</x> <y>10</y> <count>1</count> </Point2D> <Point2D> <x>10</x> <y>10</y> <count>1</count> </Point2D> </Details>
需求:将point节点按x和y值相同分组,统计每组的数量;输出忽略z元素,仅保留x、y和对应的count。
XSLT 1.0解决方案
XSLT 1.0没有原生分组功能,可通过Muenchian分组实现需求,具体代码如下:
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> <xsl:output method="xml" indent="yes"/> <!-- 定义分组键:用x和y的拼接字符串作为唯一标识,|用于避免不同组合冲突 --> <xsl:key name="pointGroup" match="point" use="concat(x, '|', y)"/> <xsl:template match="/Points"> <Details> <!-- 仅处理每组的第一个节点,避免重复输出 --> <xsl:for-each select="point[generate-id() = generate-id(key('pointGroup', concat(x, '|', y))[1])]"> <Point2D> <!-- 复制当前节点的x、y元素 --> <xsl:copy-of select="x | y"/> <!-- 统计当前分组的节点总数 --> <count> <xsl:value-of select="count(key('pointGroup', concat(x, '|', y)))"/> </count> </Point2D> </xsl:for-each> </Details> </xsl:template> </xsl:stylesheet>
代码说明
- 分组键定义:通过
<xsl:key>创建分组规则,将x和y的值拼接成唯一字符串作为分组依据。 - 分组筛选:利用
generate-id()对比,只选中每组的第一个point节点,确保每组仅输出一次。 - 数量统计:通过
count()函数获取当前分组下的节点总数,生成count元素。 - 输出结构:外层生成
<Details>容器,每组对应一个<Point2D>节点,保留原节点的x、y并添加统计结果。
内容的提问来源于stack exchange,提问作者Vineet Dwivedi
相关产品推荐
相关产品推荐

