0

我正在尝试在 XSLT/XQuery 中执行更高级的计算,但遇到了问题。该公式是聚合总和,但它在总和之前执行操作。

假设我们有以下 XML 源文件:

<day>
    <record>
        <time>2015-05-02 02:03:00-0400</time>
        <runtime>330</runtime>
        <level>51.6</level>
        <lvlmax>73.9</lvlmax>
        <lvlmin>45.1</lvlmin>
    </record>
    <record>
        <time>2015-05-02 02:18:00-0400</time>
        <runtime>215</runtime>
        <level>51.6</level>
        <lvlmax>83.9</lvlmax>
        <lvlmin>48.1</lvlmin>
    </record>
    <record>
        <time>2015-05-03 02:28:00-0400</time>
        <runtime>215</runtime>
        <level>51.6</level>
        <lvlmax>63.9</lvlmax>
        <lvlmin>40.1</lvlmin>
    </record>
</day>

这是 XPATH/XQUERY 语句。一切正常,除了“级别”计算,我们得到一个“太多的项目,预期的'1',提供了'2'”错误。公式的每一部分似乎都是独立工作的,所以我认为问题与在执行聚合函数之前对值执行操作有关。

let $hourly_records := distinct-values(//day/record/substring(time,1,13))
for $record in $hourly_records
return

        <day>   
            <time>{concat($record,':00:00-0500')}</time>    
            <runtime>{sum(//day/record[$record eq substring(time,1,13)]/runtime)}</runtime>
            <level>{20*math:log10(sum(math:exp10(//day/record[$record eq substring(time,1,13)]/level div 20)))}</level>     
            <lvlmax>{max(//day/record[$record eq substring(time,1,13)]/lvlmax)}</lvlmax>
            <lvllmin>{min(//day/record[$record eq substring(time,1,13)]/lvlmin)}</lvllmin>
        </day> 

我已经使用 SQL 来执行此操作,它会正确执行计算。它看起来像这样:

SELECT
  date_trunc('hour', time) as htime,
  sum(runtime) as runtime,
  20*log10(sum(10^(level/10)) as level,
  max(lvlmax) as lvlmax,
  min(lvlmin) as lvlmin
FROM 
  thisXML
GROUP BY 
  htime

无论如何,我不知道如何让它发挥作用。我欢迎想法和评论,希望它不是那么简单,我看起来很荒谬...... :) 哈哈

4

1 回答 1

0

以下是您可能想要的,或者至少可以使用 XQuery:

declare namespace math = "http://www.w3.org/2005/xpath-functions/math";
let $hourly_records := distinct-values(//day/record/substring(time,1,13))
for $record in $hourly_records
return

        <day>   
            <time>{concat($record,':00:00-0500')}</time>    
            <runtime>{sum(//day/record[$record eq substring(time,1,13)]/runtime)}</runtime>
            <level>{20*math:log10(sum(//day/record[$record eq substring(time,1,13)]/level/math:exp10((. div 20))))}</level>     
            <lvlmax>{max(//day/record[$record eq substring(time,1,13)]/lvlmax)}</lvlmax>
            <lvllmin>{min(//day/record[$record eq substring(time,1,13)]/lvlmin)}</lvllmin>
        </day>

结果是

<day>
   <time>2015-05-02 02:00:00-0500</time>
   <runtime>545</runtime>
   <level>57.62059991327963</level>
   <lvlmax>83.9</lvlmax>
   <lvllmin>45.1</lvllmin>
</day>
<day>
   <time>2015-05-03 02:00:00-0500</time>
   <runtime>215</runtime>
   <level>51.6</level>
   <lvlmax>63.9</lvlmax>
   <lvllmin>40.1</lvllmin>
</day>
于 2015-05-13T15:10:58.707 回答