<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>
我做了什么,所以票价是通过所有distict frontendGroupIds。我现在要做的是对每个distist frontendGroupId进行所有distict caseId的计数,但我似乎无法做到这一点。有人可以在这帮助我吗?
答案 0 :(得分:6)
你很亲密:
<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>
这导致:
2336 - 2 2337 - 3
编辑 - 哦,我发现你想要团队中的独特计数。这将是:
<!-- 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>
这看起来(诚然)有点可怕。它输出:
2336 - 1 2337 - 2
核心表达:
count(
key('kStatisticItemByGroup', @frontendGroupId)[
count(
. | key('kStatisticItemByGroupAndCase', concat(@frontendGroupId, ',', @caseId))[1]
) = 1
]
)
归结为:
计算满足以下条件的“key('kStatisticItemByGroup', @frontendGroupId)
”节点:它们是各自“kStatisticItemByGroupAndCase
”组中的第一个。
仔细观察,您会发现这并不比您已经做过的复杂。 : - )
编辑:最后一个暗示。就个人而言,我发现这比上述表达更具表现力,因为它比“count(.|something) = 1
”方法强调节点平等:
count(
key('kStatisticItemByGroup', @frontendGroupId)[
generate-id()
=
generate-id(
key('kStatisticItemByGroupAndCase', concat(@frontendGroupId, ',', @caseId))[1]
)
]
)
结果是一样的。
答案 1 :(得分:0)
你试图通过可怕的'MUENCHIAN'方法进行排序 - 我发现这种方法令人困惑,不值得尝试 - 所以我制定了自己的方法。
它使用两个转换而不是一个转换。
第一个根据您的分组要求将数据分类到正确的顺序 - 您的样本数据已经按照正确的顺序排列,因此我将其排除在此解释之外(询问您是否需要此处的帮助)
第二个转换仅通过将一个节点与下一个节点进行比较来进行分组:
<?xml version="1.0" encoding="utf-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:msxsl="urn:schemas-microsoft-com:xslt" exclude-result-prefixes="msxsl"
>
<xsl:output method="xml" indent="yes"/>
<xsl:template match="statisticItems">
<groupedItem>
<xsl:apply-templates select="statisticItem"></xsl:apply-templates>
</groupedItem>
</xsl:template>
<xsl:template match="statisticItem">
<xsl:choose>
<xsl:when test="position()=1">
<xsl:apply-templates select="@frontendGroupId" />
</xsl:when>
<xsl:when test="@frontendGroupId!=preceding-sibling::statisticItem[1]/@frontendGroupId">
<xsl:apply-templates select="@frontendGroupId" />
</xsl:when>
</xsl:choose>
<xsl:apply-templates select="@caseId" />
</xsl:template>
<xsl:template match="@frontendGroupId">
<group>
<xsl:variable name="id" select="." ></xsl:variable>
<xsl:attribute name="count">
<xsl:value-of select="count(//statisticItem/@frontendGroupId[.=$id])"/>
</xsl:attribute>
<xsl:value-of select="." />
</group>
</xsl:template>
<xsl:template match="@caseId">
<value>
<xsl:value-of select="." />
</value>
</xsl:template>
</xsl:stylesheet>
使用此方法,您可以深入了解多个组,并且仍然具有可维护的代码。