Xslt 不同的选择/分组依据 [英] Xslt distinct select / Group by

查看:20
本文介绍了Xslt 不同的选择/分组依据的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

<statisticItem id="1" frontendGroupId="2336" caseId="50264"/><statisticItem id="2" frontendGroupId="2336" caseId="50264"/><statisticItem id="3" frontendGroupId="2337" caseId="50265"/><statisticItem id="4" frontendGroupId="2337" caseId="50266"/><statisticItem id="5" frontendGroupId="2337" caseId="50266"/></statisticItems><?xml version="1.0" encoding="utf-8"?><xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"><xsl:output method="xml" omit-xml-declaration="yes"/><xsl:key name="statistic-by-frontendGroupId" match="statisticItem" use="@frontendGroupId"/><xsl:for-each select="statisticItems/statisticItem[count(.|key('statistic-by-frontendGroupId', @frontendGroupId)[1]) = 1]"><xsl:value-of select="@frontendGroupId"/></xsl:for-each>

到目前为止我所做的是遍历所有地区的前端组 ID.我现在想做的是为每个 distict frontendGroupId 计算所有 distict caseIds,但我似乎无法完成这项工作.有人可以在这里帮助我吗?

解决方案

你已经接近了:

<xsl:output method="text"/><xsl:keyname="statistic-by-frontendGroupId"匹配=统计项目"使用="@frontendGroupId"/><xsl:template match="statisticItems"><xsl:for-each select="统计项目[数数(.|key('statistic-by-frontendGroupId', @frontendGroupId)[1]) = 1]><xsl:value-of select="@frontendGroupId"/><xsl:value-of select="' - '"/><!-- 很简单:item count就是key的节点数--><xsl:value-of select="数数(key('statistic-by-frontendGroupId', @frontendGroupId))"/><xsl:value-of select="'&#10;'"/></xsl:for-each></xsl:模板></xsl:stylesheet>

结果:

<预>2336 - 22337 - 3

<小时>

编辑 - 哦,我看到您想要组内的不同计数.这将是:

<!-- 仍然定义了上述解决方案中的另一个键 --><xsl:key名称="kStatisticItemByGroupAndCase"匹配=统计项目"use="concat(@frontendGroupId, ',', @caseId)"/><xsl:template match="statisticItems"><xsl:for-each select="统计项目[数数(.|键('kStatisticItemByGroup',@frontendGroupId)[1]) = 1]><xsl:value-of select="@frontendGroupId"/><xsl:value-of select="' - '"/><xsl:value-of select="数数(键('kStatisticItemByGroup',@frontendGroupId)[数数(.|key('kStatisticItemByGroupAndCase', concat(@frontendGroupId, ',', @caseId))[1]) = 1])"/><xsl:value-of select="'&#10;'"/></xsl:for-each></xsl:模板>

这看起来(不可否认)有点吓人.它输出:

<预>2336 - 12337 - 2

核心表达:

计数(键('kStatisticItemByGroup',@frontendGroupId)[数数(.|key('kStatisticItemByGroupAndCase', concat(@frontendGroupId, ',', @caseId))[1]) = 1])

归结为:

计算key('kStatisticItemByGroup', @frontendGroupId)"中满足以下条件的节点:它们是各自kStatisticItemByGroupAndCase"组中的第一个.

仔细观察,你会发现这并不比你已经做的更复杂.:-)

<小时>

最后一个提示.就个人而言,我发现这比上述表达式更具表现力,因为它比count(.|something) = 1"方法更强调节点相等性:

计数(键('kStatisticItemByGroup',@frontendGroupId)[生成 ID()=生成 ID(key('kStatisticItemByGroupAndCase', concat(@frontendGroupId, ',', @caseId))[1])])

结果是一样的.

<statisticItems>
    <statisticItem id="1" frontendGroupId="2336" caseId="50264"  />
    <statisticItem id="2" frontendGroupId="2336" caseId="50264"  />
    <statisticItem id="3" frontendGroupId="2337" caseId="50265"  />
    <statisticItem id="4" frontendGroupId="2337" caseId="50266"  />
    <statisticItem id="5" frontendGroupId="2337" caseId="50266"  />
</statisticItems>

<?xml version="1.0" encoding="utf-8"?>
  <xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
  <xsl:output method="xml" omit-xml-declaration="yes"/>

  <xsl:key name="statistic-by-frontendGroupId" match="statisticItem" use="@frontendGroupId" />

  <xsl:for-each select="statisticItems/statisticItem[count(.|key('statistic-by-frontendGroupId', @frontendGroupId)[1]) = 1]">
       <xsl:value-of select="@frontendGroupId"/>
  </xsl:for-each>

What i have done so fare is to go through all distict frontendGroupIds. What i would like to do now is to do a count of all the distict caseIds for each distict frontendGroupId but i cant seem to make that work. Can someone help me here plz?

解决方案

You were close:

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">

  <xsl:output method="text" />

  <xsl:key 
    name="statistic-by-frontendGroupId" 
    match="statisticItem" 
    use="@frontendGroupId" 
  />

  <xsl:template match="statisticItems">
    <xsl:for-each select="
      statisticItem[
        count(
          . | key('statistic-by-frontendGroupId', @frontendGroupId)[1]
        ) = 1
      ]
    ">
      <xsl:value-of select="@frontendGroupId"/>
      <xsl:value-of select="' - '"/>
      <!-- simple: the item count is the node count of the key -->
      <xsl:value-of select="
        count(
          key('statistic-by-frontendGroupId', @frontendGroupId)
        )
      "/>
      <xsl:value-of select="'&#10;'"/>
    </xsl:for-each>
  </xsl:template>

</xsl:stylesheet>

This results in:

2336 - 2
2337 - 3


EDIT - Oh, I see you want the distinct count within the group. This would be:

<!-- the other key from the above solution is still defined -->

<xsl:key 
  name="kStatisticItemByGroupAndCase" 
  match="statisticItem" 
  use="concat(@frontendGroupId, ',', @caseId)"
/>

<xsl:template match="statisticItems">
  <xsl:for-each select="
    statisticItem[
      count(
        . | key('kStatisticItemByGroup', @frontendGroupId)[1]
      ) = 1
    ]
  ">
    <xsl:value-of select="@frontendGroupId"/>
    <xsl:value-of select="' - '"/>
    <xsl:value-of select="
      count(
        key('kStatisticItemByGroup', @frontendGroupId)[
          count(
            . | key('kStatisticItemByGroupAndCase', concat(@frontendGroupId, ',', @caseId))[1]
          ) = 1
        ]
      )
    "/>
    <xsl:value-of select="'&#10;'"/>
  </xsl:for-each>
</xsl:template>

Which looks (admittedly) a bit frightening. It outputs:

2336 - 1
2337 - 2

The core expression:

count(
  key('kStatisticItemByGroup', @frontendGroupId)[
    count(
      . | key('kStatisticItemByGroupAndCase', concat(@frontendGroupId, ',', @caseId))[1]
    ) = 1
  ]
)

boils down to:

Count the nodes from "key('kStatisticItemByGroup', @frontendGroupId)" that fulfill the following condition: They are the first in their respective "kStatisticItemByGroupAndCase" group.

Looking closely, you will find that this is no more complicated than what you already do. :-)


EDIT: One last hint. Personally, I find this a lot more expressive than the above expressions, because it emphasizes node equality a lot more than the "count(.|something) = 1" approach:

count(
  key('kStatisticItemByGroup', @frontendGroupId)[
    generate-id()
    =
    generate-id(
      key('kStatisticItemByGroupAndCase', concat(@frontendGroupId, ',', @caseId))[1]
    )
  ]
)

The result is the same.

这篇关于Xslt 不同的选择/分组依据的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆