Xquery根据条件对结果进行分组

发布于 2024-10-04 14:48:48 字数 1325 浏览 8 评论 0原文

我有一个关于 xquery 分组的问题。据我了解,通常的情况是在 for 循环中的文档上使用 distinct-values ,但是因为我在对值进行分组之前需要满足一个条件,而且我不太确定如何这是可以做到的。

这是我的 xmldb 的一部分:

<element tag="0001,0000" name="Pos1>198</element>
<element tag="0001,0001" name="Pos2">123</name>
<element tag="0002,0001" name="Pos3">433</element>
<element tag="000b,0000" name="Pos3">16</element>
<element tag="0005,0000" name="Pos4>532</element>
<element tag="0005,0001" name="Pos5">342</name>
<element tag="0008,0001" name="Pos6">17</element>

要满足的条件是 x 坐标(数字或十六进制)必须为奇数值(例如,从上面的 xml 中,我只需要 tag="0001,..." 的结果, tag="000b,...", tag="0005,..."),然后计算每组中有多少个项目。

结果应该是这样的:

<group>
<element xcoord="0001">2</element>
<element xcoord="000b">1</element>
<element xcoord="0005">2</element>
</group>

到目前为止,我的 xquery 代码看起来像这样,我可以生成具有奇数 x 坐标的结果,但我不知道如何从这里继续进行分组。

import module namespace functx="http://www.functx.com" at "http://www.xqueryfunctions.com/xq/functx-1.0-nodoc-2007-01.xq"; 

for $x in collection('/db/mapdb/')//element
let $coord := number(functx:substring-before-last($x/@tag, ","))
where $coord mod 2 != 0
return $x

请给我建议。非常感谢。

I have a question on xquery grouping. From what I understand, the usual case would be to use distinct-values on the docs in the for loop, however as I have a condition to fulfill before grouping the values, and I am not quite sure how this can be done.

This is part of my xmldb:

<element tag="0001,0000" name="Pos1>198</element>
<element tag="0001,0001" name="Pos2">123</name>
<element tag="0002,0001" name="Pos3">433</element>
<element tag="000b,0000" name="Pos3">16</element>
<element tag="0005,0000" name="Pos4>532</element>
<element tag="0005,0001" name="Pos5">342</name>
<element tag="0008,0001" name="Pos6">17</element>

The condition to fulfill is that the x-coordinates (number or hexdec) have to be in odd values (e.g. from the above xml, i would only need results from tag="0001,...", tag="000b,...", tag="0005,..."), and then count how many items in each group.

This is how the results should look like:

<group>
<element xcoord="0001">2</element>
<element xcoord="000b">1</element>
<element xcoord="0005">2</element>
</group>

My xquery code so far looks like this, where I could generate results that have odd x-coordinates, but I have no idea how to proceed on from here for the grouping.

import module namespace functx="http://www.functx.com" at "http://www.xqueryfunctions.com/xq/functx-1.0-nodoc-2007-01.xq"; 

for $x in collection('/db/mapdb/')//element
let $coord := number(functx:substring-before-last($x/@tag, ","))
where $coord mod 2 != 0
return $x

Kindly advise me. Thank you very much.

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

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

发布评论

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

评论(4

茶底世界 2024-10-11 14:48:48

此 XQuery

for $x in 
  distinct-values(/*/*/substring-before(@tag,',')
                    [contains('13579bdf', 
                               substring(., string-length(.))
                              )
                     ]
                  )
 return
   <element xcoord="{$x}">
    {count(/*/*[$x eq substring-before(@tag,',')])}
   </element>

产生所需的正确结果

<element xcoord="0001">2</element>
<element xcoord="000b">1</element>
<element xcoord="0005">2</element>

This XQuery:

for $x in 
  distinct-values(/*/*/substring-before(@tag,',')
                    [contains('13579bdf', 
                               substring(., string-length(.))
                              )
                     ]
                  )
 return
   <element xcoord="{$x}">
    {count(/*/*[$x eq substring-before(@tag,',')])}
   </element>

produces the wanted, correct result:

<element xcoord="0001">2</element>
<element xcoord="000b">1</element>
<element xcoord="0005">2</element>
日记撕了你也走了 2024-10-11 14:48:48

此 XQuery:

<group>{
    for $key in distinct-values(/root/element/tokenize(@tag,',')[1])
                   [contains('13579bdf',substring(.,string-length(.)))]
    return <element xcoord="{$key}">{
               count(/root/element[tokenize(@tag,',')[1] eq $key])
          }</element>
}</group>

使用此输入:

<root>
    <element tag="0001,0000" name="Pos1">198</element>
    <element tag="0001,0001" name="Pos2">123</element>
    <element tag="0002,0001" name="Pos3">433</element>
    <element tag="000b,0000" name="Pos3">16</element>
    <element tag="0005,0000" name="Pos4">532</element>
    <element tag="0005,0001" name="Pos5">342</element>
    <element tag="0008,0001" name="Pos6">17</element>
</root>

输出:

<group>
    <element xcoord="0001">2</element>
    <element xcoord="000b">1</element>
    <element xcoord="0005">2</element>
</group>

注意:除了 eqne 之外,xs:hexBinary 数据类型没有内置运算符。

This XQuery:

<group>{
    for $key in distinct-values(/root/element/tokenize(@tag,',')[1])
                   [contains('13579bdf',substring(.,string-length(.)))]
    return <element xcoord="{$key}">{
               count(/root/element[tokenize(@tag,',')[1] eq $key])
          }</element>
}</group>

With this input:

<root>
    <element tag="0001,0000" name="Pos1">198</element>
    <element tag="0001,0001" name="Pos2">123</element>
    <element tag="0002,0001" name="Pos3">433</element>
    <element tag="000b,0000" name="Pos3">16</element>
    <element tag="0005,0000" name="Pos4">532</element>
    <element tag="0005,0001" name="Pos5">342</element>
    <element tag="0008,0001" name="Pos6">17</element>
</root>

Output:

<group>
    <element xcoord="0001">2</element>
    <element xcoord="000b">1</element>
    <element xcoord="0005">2</element>
</group>

Note: There is no built-in operator for xs:hexBinary data type except for eq and ne.

梦归所梦 2024-10-11 14:48:48

你没有说你正在使用哪个处理器。我在 try.zorba-xquery.com 上测试了以下代码(它也应该适用于 Saxon 或其他支持 XQuery 1.1 和 XPath 2.0 的处理器):

let $xmldb :=
  (
    <element tag="0001,0000" name="Pos1">198</element>,
    <element tag="0001,0001" name="Pos2">123</element>,
    <element tag="0002,0001" name="Pos3">433</element>,
    <element tag="000b,0000" name="Pos3">16</element>,
    <element tag="0005,0000" name="Pos4">532</element>,
    <element tag="0005,0001" name="Pos5">342</element>,
    <element tag="0008,0001" name="Pos6">17</element>
  )
for $x in $xmldb
let $coord := tokenize($x/@tag, ",")[1]
group by $coord
where contains('13579bdf',substring($coord,string-length($coord)))
return <element xcoord="{$coord}">{count($x)}</element>

希望有帮助吗?

You didn't say which processor you are using. I tested the following code on try.zorba-xquery.com (it should also work for Saxon or other processors supporting XQuery 1.1 and XPath 2.0):

let $xmldb :=
  (
    <element tag="0001,0000" name="Pos1">198</element>,
    <element tag="0001,0001" name="Pos2">123</element>,
    <element tag="0002,0001" name="Pos3">433</element>,
    <element tag="000b,0000" name="Pos3">16</element>,
    <element tag="0005,0000" name="Pos4">532</element>,
    <element tag="0005,0001" name="Pos5">342</element>,
    <element tag="0008,0001" name="Pos6">17</element>
  )
for $x in $xmldb
let $coord := tokenize($x/@tag, ",")[1]
group by $coord
where contains('13579bdf',substring($coord,string-length($coord)))
return <element xcoord="{$coord}">{count($x)}</element>

Hope that helps?

彩虹直至黑白 2024-10-11 14:48:48

如果您使用的是 XQuery 1.0 处理器,则分组依据的常用模式是:

let $values := ...
for $key in distinct-values(for $value in $values return my:key($value))
let $group := $values[my:key(.)=$key]
return ...

其中 my:key 是获取每个输入值的键的函数/表达式。

在您的情况下,您可以如下填写模式:

for $coord in distinct-values($xmldb/(tokenize(.,",")[1]))
let $x := $xmldb[tokenize(.,",")[1] = $coord]
return <element xcoord="{$coord}">{count($x)}</element>

此操作是否有效取决于您的实现。我写了一篇关于如何编写XQSharp 能够识别的分组。

编辑:我错过了所有 x 坐标必须为奇数的要求。这可以通过添加一个 where 子句来约束坐标的最后一个字符来解决:

for $coord in distinct-values($xmldb/(tokenize(.,",")[1]))
where contains('13579bdf',substring($coord,string-length($coord)))
let $x := $xmldb[tokenize(.,",")[1] = $coord]
return <element xcoord="{$coord}">{count($x)}</element>

If you are using an XQuery 1.0 processor then the usual pattern for a group by is:

let $values := ...
for $key in distinct-values(for $value in $values return my:key($value))
let $group := $values[my:key(.)=$key]
return ...

where my:key is a function/expression that obtains the key for each input value.

In your case you can fill in the pattern as so:

for $coord in distinct-values($xmldb/(tokenize(.,",")[1]))
let $x := $xmldb[tokenize(.,",")[1] = $coord]
return <element xcoord="{$coord}">{count($x)}</element>

Whether or not this perform efficiently depends on your implementation. I have written a blog post on how to write a group by that XQSharp will recognise.

Edit: I missed the requirement that all x coordinates must be odd. This can be fixed with the addition of a where clause to constrain the last character of the coordinate:

for $coord in distinct-values($xmldb/(tokenize(.,",")[1]))
where contains('13579bdf',substring($coord,string-length($coord)))
let $x := $xmldb[tokenize(.,",")[1] = $coord]
return <element xcoord="{$coord}">{count($x)}</element>
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文