XQuery 方法,尝试对从 xml 读取的值求和

发布于 2024-08-14 12:29:05 字数 1620 浏览 2 评论 0原文

我对 XQuery 还很陌生,我正在尝试编写一个无法运行的示例函数。 我想读取一个 xml 文件,解析出“时间”值,在读取时对它们求和并返回总和。 这是微不足道的,我希望在其中构建更多功能,但我想首先让它工作。 另外,我知道 XQuery 中有一个“sum”指令可以完成此操作,但我想添加更多内容,因此内置的 sum 不足以满足我的需要。

这是我的函数:

bool
example(Zorba* aZorba)
{
   XQuery_t lQuery = aZorba->compileQuery(
                        "for $i in fn:doc('/tmp/products.xml')//time"
                         "let $sum := xs:integer($i)"
                                 " return $sum"
);

  DynamicContext* lCtx = lQuery->getDynamicContext();

  lCtx->setContextItemAsDocument("temp_measurements.xml", lDocStream);

  try {
    std::cout << lQuery << std::endl;
  } catch (DynamicException& e) {
    std::cerr << e.getDescription() << std::endl;
    return false;
  } catch (StaticException& f){
        std::cerr << f.getDescription() << f.getErrorCodeAsString(f.getErrorCode()) << std::endl;
        return false;
  }
}

它是用适当的 main() 调用的。如果我注释掉以“let $sum...”开头的行,那么它会以一系列整数形式返回时间值,如下所示: 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 3 3 3 3 3 3 3 3 3....

输入文件看起来像这样:

<?xml version="1.0" encoding="UTF-8"?>
<temps>
  <temp>
    <time>0</time>
    <lat>0</lat>
    <long>0</long>
    <value>0</value>
  </temp>
  <temp>
    <time>1</time>
    <lat>0</lat>
    <long>1</long>
    <value>0</value>
  </temp>
 ...

I'm pretty new to XQuery and I'm trying to write an example function that I can't get to work.
I want to read an xml file, parse out the "time" values, sum them as they're read and return the sum.
This is trivial and I'm looking to build more functionality into it but I'd like to get this working first.
Also, I know there's a "sum" directive in XQuery that would do just this but I want to add more to it so the built-in sum is insufficient for my needs.

Here's my function:

bool
example(Zorba* aZorba)
{
   XQuery_t lQuery = aZorba->compileQuery(
                        "for $i in fn:doc('/tmp/products.xml')//time"
                         "let $sum := xs:integer($i)"
                                 " return $sum"
);

  DynamicContext* lCtx = lQuery->getDynamicContext();

  lCtx->setContextItemAsDocument("temp_measurements.xml", lDocStream);

  try {
    std::cout << lQuery << std::endl;
  } catch (DynamicException& e) {
    std::cerr << e.getDescription() << std::endl;
    return false;
  } catch (StaticException& f){
        std::cerr << f.getDescription() << f.getErrorCodeAsString(f.getErrorCode()) << std::endl;
        return false;
  }
}

It's called with an appropriate main(). If I comment out the line that starts "let $sum..." then this works in that it returns the time values as a series of integers like this:
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 3 3 3 3 3 3 3 3 3....

Input file looks like this:

<?xml version="1.0" encoding="UTF-8"?>
<temps>
  <temp>
    <time>0</time>
    <lat>0</lat>
    <long>0</long>
    <value>0</value>
  </temp>
  <temp>
    <time>1</time>
    <lat>0</lat>
    <long>1</long>
    <value>0</value>
  </temp>
 ...

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

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

发布评论

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

评论(2

风蛊 2024-08-21 12:29:05

看起来您想像

这样使用 fn:sum :

fn:sum(
    (
        1, 1, 1, 1, 0, 0, 1, 0
    ), 
    0
)

更多信息在这里: http://www .xqueryfunctions.com/xq/fn_sum.html

its looks like you want to use fn:sum

like this:

fn:sum(
    (
        1, 1, 1, 1, 0, 0, 1, 0
    ), 
    0
)

More information here: http://www.xqueryfunctions.com/xq/fn_sum.html

昨迟人 2024-08-21 12:29:05

我自己对 XQuery 来说是一个相对较新的人,但令我感到惊讶的一件事是缺少像 LISP 中那样的 map() 函数,用于获取一系列值并将它们组合成一个,并传入组合函数。在 LISP 中,我认为你想要类似“(map '+ (0 0 0 1 1 2 2 3 1 2))”的东西。您可以在 XQuery 中执行类似的操作,但您必须自己编写:

declare function local:sum-times($seq)
{
  if (count($seq) < 2)
  then
    subsequence($seq, 1, 1)
  else
    subsequence($seq, 1, 1) + local:sum-times(subsequence($seq, 2))
};

因此您可以编写“local:sum-times(for $i in fn:doc()...)”。基本上,这会重新创建您提到的 sum() 函数,但现在您可以进行所需的更改。

I'm a relative newcomer to XQuery myself, but one of the things I was surprised about was the lack of a map() function, as in LISP, to take a sequence of values and combine them into one, passing in the combining function. In LISP, I think you'd want something like "(map '+ (0 0 0 1 1 2 2 3 1 2))". You can do something similar in XQuery, but you have to write it yourself:

declare function local:sum-times($seq)
{
  if (count($seq) < 2)
  then
    subsequence($seq, 1, 1)
  else
    subsequence($seq, 1, 1) + local:sum-times(subsequence($seq, 2))
};

So then you can write "local:sum-times(for $i in fn:doc()...)". Basically, this recreates the sum() function you mentioned, but now you can make the changes you need.

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