XSLT 1.0中如何获取指定节点集中出现最频繁的属性值?
XSLT 1.0 实现指定参数统计与最频值查找
核心需求回顾
统计满足以下条件的<parameter>节点@name属性的出现次数,并找出出现最频繁的值:
- 所属
<command>节点的commands_type属性为WEATHER - 自身
under_control属性为false
正确实现代码
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> <xsl:output method="text" encoding="UTF-8"/> <!-- 定义Muenchian分组键:按符合条件的parameter节点的@name分组 --> <xsl:key name="param-group" match="command[@commands_type='WEATHER']/parameter[@under_control='false']" use="@name"/> <xsl:template match="/"> <!-- 第一步:计算所有分组中的最大出现次数 --> <xsl:variable name="max-occurrence"> <xsl:for-each select="command[@commands_type='WEATHER']/parameter[@under_control='false'] [generate-id() = generate-id(key('param-group', @name)[1])]"> <!-- 按出现次数降序排序 --> <xsl:sort select="count(key('param-group', @name))" data-type="number" order="descending"/> <!-- 取第一个(次数最多的)分组的次数 --> <xsl:if test="position() = 1"> <xsl:value-of select="count(key('param-group', @name))"/> </xsl:if> </xsl:for-each> </xsl:variable> <!-- 第二步:找到次数等于最大值的@name并输出 --> <xsl:for-each select="command[@commands_type='WEATHER']/parameter[@under_control='false'] [generate-id() = generate-id(key('param-group', @name)[1])]"> <xsl:if test="count(key('param-group', @name)) = $max-occurrence"> <xsl:text>commonest param is: </xsl:text> <xsl:value-of select="@name"/> </xsl:if> </xsl:for-each> </xsl:template> </xsl:stylesheet>
关键细节说明
分组键的正确定义
键的match路径严格限定了筛选条件:仅匹配commands_type='WEATHER'的<command>下、under_control='false'的<parameter>节点,确保统计范围准确。最大次数的计算
通过对所有唯一分组(每个@name的第一个节点)按出现次数降序排序,取第一个节点的次数作为最大值,这是XSLT 1.0中获取极值的常用方式。常见错误排查
你之前得到错误结果weather_intensity,大概率是因为属性值匹配方式错误:- 如果XML中
under_control的属性值是字符串"false",但你的代码中写了@under_control=false(无引号),XSLT 1.0会将字符串"false"转换为布尔值true(非空字符串均为真),导致筛选条件失效,统计了不符合要求的节点。必须使用字符串匹配@under_control='false'。
- 如果XML中
特殊情况处理(可选)
如果存在多个@name出现次数相同且均为最大值的情况,上述代码会输出所有符合条件的值。若只需输出第一个,可在第二个<xsl:for-each>中添加降序排序,并在position()=1时输出。
内容的提问来源于stack exchange,提问作者Quinn Carver
相关产品推荐
相关产品推荐

