检测最后一个分组后元组

时间:2015-02-06 16:22:03

标签: xquery xquery-3.0

在XQuery 3.0中,如何检测由return子句产生的 last 后分组元组(由XQuery 3.0 spec定义)?是否可以使用position() = last()之类的东西? position函数的上下文是什么?

例如,假设我想通过XQuery生成CSV输出。为了分隔CSV输出中的行,我在return子句生成的每个元组后附加一个换行符:

xquery version "3.0";

declare option saxon:output "omit-xml-declaration=yes";
declare option saxon:output "method=text";

declare variable $data := (
    <items>
        <item>
            <property name="a"/>
            <property name="a"/>
            <property name="b"/>
        </item>
        <item>
            <property name="a"/>
        </item>
        <item>
            <property name="b"/>
            <property name="c"/>
            <property name="d"/>
        </item>
        <item>
            <property name="b"/>
            <property name="c"/>
        </item>
    </items>
);

for $item in $data/item,
    $name in $item/property/@name
group by $name
return (
    text{string-join(($name, string(count($item))), ",")},
    text{"&#10;"}
)

但是,这会在最后一个元组之后留下一个空行。如果我可以测试元组位置,我可以避免在最后一个元组后添加换行符。

1 个答案:

答案 0 :(得分:2)

这里的XQuery规范确实似乎缺少像group by $variable at $position这样的东西,类似于for子句中允许的内容。再次阅读XQuery 3.0 specs,我找不到任何有用的东西。 position()last()需要一个节点上下文,这在循环中不可用。

但是关于你的潜在问题:为什么不使用另一个string-join(...)将项目与中间的换行连接起来,类似于你对计数所做的那样?

string-join(
  for $item in $data/item,
      $name in $item/property/@name
  group by $name
  return (
      text{string-join(($name, string(count($item))), ",")}
  ),
  text{"&#10;"}
)