如何计算节点中的不同值?

Posted

技术标签:

【中文标题】如何计算节点中的不同值?【英文标题】:How to count distinct values in a node? 【发布时间】:2010-09-14 06:25:03 【问题描述】:

如何在 XSLT 中计算节点中的不同值?

示例:我想统计 Country 节点中现有国家的数量,在本例中为 3。

<Artists_by_Countries>
    <Artist_by_Country>
        <Location_ID>62</Location_ID>
        <Artist_ID>212</Artist_ID>
        <Country>Argentina</Country>
    </Artist_by_Country>
    <Artist_by_Country>
        <Location_ID>4</Location_ID>
        <Artist_ID>108</Artist_ID>
        <Country>Australia</Country>
    </Artist_by_Country>
    <Artist_by_Country>
        <Location_ID>4</Location_ID>
        <Artist_ID>111</Artist_ID>
        <Country>Australia</Country>
    </Artist_by_Country>
    <Artist_by_Country>
        <Location_ID>12</Location_ID>
        <Artist_ID>78</Artist_ID>
        <Country>Germany</Country>
    </Artist_by_Country>
</Artists_by_Countries>

【问题讨论】:

【参考方案1】:

如果您的文档很大,您可能希望使用通常用于分组的“Muenchian 方法”来识别不同的节点。声明一个键,通过不同的值来索引您想要计数的事物:

<xsl:key name="artists-by-country" match="Artist_by_Country" use="Country" />

然后您可以使用以下方式获取具有不同国家/地区的&lt;Artist_by_Country&gt; 元素:

/Artists_by_Countries
  /Artist_by_Country
    [generate-id(.) =
     generate-id(key('artists-by-country', Country)[1])]

您可以通过将其包装在对count() 函数的调用中来计算它们。

当然在 XSLT 2.0 中,它就这么简单

count(distinct-values(/Artists_by_Countries/Artist_by_Country/Country))

【讨论】:

我的眼睛在上面的一堆线条上闪闪发光,然后我在最后找到了金块【参考方案2】:

在 XSLT 1.0 中这并不明显,但以下内容应该让您了解需求:

count(//Artist_by_Country[not(Location_ID=preceding-sibling::Artist_by_Country/Location_ID)]/Location_ID)

XML 中的元素越多,所需的时间就越长,因为它会检查每个元素的每个前面的兄弟元素。

【讨论】:

不确定性能,但对于 XSLT 1.0,这似乎比在投票最多的解决方案中要求 元素更简洁。 在 XSLT 中通常至少有两种方法可以给猫剥皮——哪种方法最好取决于您的具体情况。与我怀疑的上述方法相比,xsl:key 在大型文档的良好处理器中可以非常快。【参考方案3】:

试试这样的:

count(//Country[not(following::Country/text() = text())])

“给我所有 Country 节点的计数,没有以下 Country 和匹配的文本”

IMO 这个表达式的有趣之处在于 following 轴。

您也可以删除第一个/text(),并将第二个替换为.

【讨论】:

这仅在节点已排序并且类似的 Country 值因此是连续的情况下才有效。 不,它总是有效的。 following:: 作用于整个文档,如果上下文之一之后有任何国家具有相同的值,则该节点将不被计算在内。 这应该是公认的答案,尽管 2.0 选项非常适合可以使用它的人。【参考方案4】:

如果您在第一次出现国家/地区时可以控制 xml 生成,则可以向国家节点添加一个属性,例如 distinct='true' 将国家标记为“已使用”,如果您随后不添加 distinct 属性再次遇到那个国家。

你可以这样做

<xsl:for-each select="Artists_by_Countries/Artist_by_Country/Country[@distinct='true']" />

【讨论】:

以上是关于如何计算节点中的不同值?的主要内容,如果未能解决你的问题,请参考以下文章

如何按对象计算熊猫组列中的不同值?

VBA |如何计算不同值的出现次数?

在 XSLT 中,如何计算给定属性值的每个不同值出现在输入 XML 中的次数?

根据节点值为networkx中的节点绘制不同的颜色

r 由两个不同栅格确定的单元格中的栅格砖总和值,如何加快计算速度

如何在SQL Server 2012中的10个不同节点中转换此字符串?