如何统计同名元素的个数? XML->查询

发布于 2024-11-05 18:44:50 字数 595 浏览 0 评论 0原文

我有一个 xml 文档,例如:

<root>
<test>
    <humans>
        <names>Tim</names>
    </humans>
</test>
<test>
    <humans>
        <names>Jack</names>
        <names>Jones</names>
    </humans>
</test>
<test>
    <humans>
        <names>Tim</names>
    </humans>
</test>
</root>

我想计算所有相同的名称: Tim 2、Jack 1、Jones 1 它应该给出这样的输出:

<x> Tim </x> 

因为 TIM 是最高的名字

我希望你能帮助我......(对不起我的英语不好)

i have a xml doc like:

<root>
<test>
    <humans>
        <names>Tim</names>
    </humans>
</test>
<test>
    <humans>
        <names>Jack</names>
        <names>Jones</names>
    </humans>
</test>
<test>
    <humans>
        <names>Tim</names>
    </humans>
</test>
</root>

and I want to count all names which are the same: Tim 2, Jack 1, Jones 1
and it should give an output like:

<x> Tim </x> 

because TIM is the highest name

I hope you can help me... (sorry for my bad english)

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

债姬 2024-11-12 18:44:50

在 XPath 2.0、XSLT 2.0 和 XQuery 中使用(完全相同的解决方案):

(/*/*/*/names[for $v in .,
                    $cnt in count(/*/*/*/names[. eq $v])
                 return
                    $cnt
                   eq
                     max(for $n in distinct-values(/*/*/*/names)
                           return
                              count(/*/*/*/names[. eq $n])
                        )
                ]
    )[1]

您也可以通过以下 XSLT 1.0 转换轻松获取此元素

<xsl:stylesheet version="1.0"
 xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
 <xsl:output omit-xml-declaration="yes" indent="yes"/>
 <xsl:key name="kNamesByVal" match="names" use="."/>

 <xsl:template match="/">
  <xsl:for-each select=
   "*/*/*/names[generate-id()
               =
                generate-id(key('kNamesByVal',.)[1])
               ]">
   <xsl:sort select="count(key('kNamesByVal',.))"
    data-type="number" order="descending"/>

    <xsl:if test="position()=1">
      <xsl:copy-of select="."/>
    </xsl:if>
  </xsl:for-each>
 </xsl:template>
</xsl:stylesheet>

当上面在提供的 XML 文档上评估(应用)XPath 2.0/XQuery 表达式或 XSLT 转换

<root>
    <test>
        <humans>
            <names>Tim</names>
        </humans>
    </test>
    <test>
        <humans>
            <names>Jack</names>
            <names>Jones</names>
        </humans>
    </test>
    <test>
        <humans>
            <names>Tim</names>
        </humans>
    </test>
</root>

选择(生成)正确的元素:

<names>Tim</names>

In XPath 2.0, XSLT 2.0 and XQuery use (exactly the same solution):

(/*/*/*/names[for $v in .,
                    $cnt in count(/*/*/*/names[. eq $v])
                 return
                    $cnt
                   eq
                     max(for $n in distinct-values(/*/*/*/names)
                           return
                              count(/*/*/*/names[. eq $n])
                        )
                ]
    )[1]

You can also get this element easily with the following XSLT 1.0 transformation:

<xsl:stylesheet version="1.0"
 xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
 <xsl:output omit-xml-declaration="yes" indent="yes"/>
 <xsl:key name="kNamesByVal" match="names" use="."/>

 <xsl:template match="/">
  <xsl:for-each select=
   "*/*/*/names[generate-id()
               =
                generate-id(key('kNamesByVal',.)[1])
               ]">
   <xsl:sort select="count(key('kNamesByVal',.))"
    data-type="number" order="descending"/>

    <xsl:if test="position()=1">
      <xsl:copy-of select="."/>
    </xsl:if>
  </xsl:for-each>
 </xsl:template>
</xsl:stylesheet>

When the above XPath 2.0/XQuery expression or XSLT transformation are evaluated (applied) on the provided XML document:

<root>
    <test>
        <humans>
            <names>Tim</names>
        </humans>
    </test>
    <test>
        <humans>
            <names>Jack</names>
            <names>Jones</names>
        </humans>
    </test>
    <test>
        <humans>
            <names>Tim</names>
        </humans>
    </test>
</root>

the correct element is selected (produced):

<names>Tim</names>
戈亓 2024-11-12 18:44:50
let $xml := <!-- your xml document -->
return
(
  for $name in distinct-values($xml//names)
  order by count($xml//names[. = $name]) descending
  return <x>{$name}</x>
)[1]
let $xml := <!-- your xml document -->
return
(
  for $name in distinct-values($xml//names)
  order by count($xml//names[. = $name]) descending
  return <x>{$name}</x>
)[1]
冷月断魂刀 2024-11-12 18:44:50

Gunther 的解决方案是最好的,如果您想计算您可以做的每个元素:

xquery version "1.0";

for $x in
(
  for $name in distinct-values(//names)
  order by count(//names[. = $name]) descending
  return <x>{$name}</x>
) return fn:concat($x, ' - ',xs:string(count(//names[. = $x])))

结果 Tim - 2 Jack - 1 Johons - 1

The solution of Gunther is the best, and if you wanted to count every elements you could do:

xquery version "1.0";

for $x in
(
  for $name in distinct-values(//names)
  order by count(//names[. = $name]) descending
  return <x>{$name}</x>
) return fn:concat($x, ' - ',xs:string(count(//names[. = $x])))

With result Tim - 2 Jack - 1 Johons - 1

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文