Xslt 不同的选择/分组依据 [英] Xslt distinct select / Group by
问题描述
<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="' '"/></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="' '"/></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="' '"/>
</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="' '"/>
</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屋!