Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/xml/12.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
如何计算同名元素的数量?XML->;Xquery_Xml_Xslt_Xpath_Count_Xquery - Fatal编程技术网

如何计算同名元素的数量?XML->;Xquery

如何计算同名元素的数量?XML->;Xquery,xml,xslt,xpath,count,xquery,Xml,Xslt,Xpath,Count,Xquery,我有一个xml文档,如: <root> <test> <humans> <names>Tim</names> </humans> </test> <test> <humans> <names>Jack</names> <names>Jones</names> &l

我有一个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>

提姆
杰克
琼斯
提姆
我想数一数所有相同的名字:蒂姆2号,杰克1号,琼斯1号 它应该给出如下输出:

<x> Tim </x> 
Tim
因为蒂姆是最高的名字


我希望你能帮助我。。。(很抱歉我的英语不好)

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

您还可以通过以下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>
<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>

在提供的XML文档上计算(应用)上述XPath 2.0/XQuery表达式或XSLT转换时

<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>
<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>
Tim
让$xml:=
返回
(
对于不同值中的$name($xml//names)
按计数排序($xml//names[.=$name])降序
返回{$name}
)[1]

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])))
xquery版本“1.0”;
十美元
(
对于不同值(//名称)中的$name
按计数排序(//names[.=$name])降序
返回{$name}
)返回fn:concat($x,'-',xs:string(count(//names[.=$x]))

结果Tim-2杰克-1约翰-1

问得好,+1。有关两个完整、简短且简单的解决方案(XPath 2.0/XQuery和XSLT 1.0),请参见我的答案。可以看出,使用XPath表达式具有更好的可移植性,可以在XQuery和XSLT 2.0中以及承载XPath 2.0的任何语言中不加更改地使用。这将加载一个文件:
let$xml:=doc(“data.xml”)