XQuery:如何在序列后面添加逗号(最后一个元素除外)

XQuery:如何在序列后面添加逗号(最后一个元素除外),xquery,xpath-2.0,Xquery,Xpath 2.0,我有以下xml: <form> <bibl> <biblScope>1</biblScope> <biblScope>a</biblScope> </bibl> <bibl> <biblScope>2</biblScope> <biblScope>b</biblScope> </bibl> <bibl&g

我有以下xml:

<form>
<bibl>
    <biblScope>1</biblScope>
    <biblScope>a</biblScope>
</bibl>
<bibl>
    <biblScope>2</biblScope>
    <biblScope>b</biblScope>
</bibl>
<bibl>
    <biblScope>38</biblScope>
    <biblScope>c</biblScope>
</bibl>
</form>
这绝对是错误的,因为我想要的是

<div>1a,</div>
<div>2b,</div>
<div>38c@</div>
1a,
2b,
38c@
(在每个
bibl
元素内容后添加一个逗号;最后一个元素后面应该是
@
,而不是逗号。)

我已经尝试了不同的事情一段时间了,我可能需要一些帮助。正确的方法是什么?

首先请注意:

for $biblScope in $bibl/biblScope/text()
    return
    $biblScope
可替换为:

$bibl/biblScope/text()
<div>{string-join($bibl/biblScope, ',')}@</div>
(这一点冗长是一个令人惊讶的常见错误。它表明你在按程序思考——一次处理一个项目,而不是处理集合。)

那么这个,

<div>
{$bibl/biblScope/text()}
{if ($bibl[position()] ne $bibl[last()]) then ',' else '@'}
</div> 

{$bibl/biblScope/text()}
{如果($bibl[position()]ne$bibl[last()]),那么,''else'@'}
应替换为以下内容:

$bibl/biblScope/text()
<div>{string-join($bibl/biblScope, ',')}@</div>
{string join($bibl/biblScope,,')}@

请注意,我还消除了不必要的(可以说是不正确的)使用
/text()
,这是另一种XQuery反模式。

问题是
position()
last()
在当前上下文上工作,而当前上下文不是由flwor表达式设置的。如果要使用类似的语义,请使用
at$position
语法获取位置计数器,并将
$last
定义为结果数:

let $last := count(form/bibl)
for $bibl at $position in form/bibl 
return
<div>
{
for $biblScope in $bibl/biblScope/text()
    return
    $biblScope
}
{if ($position ne $last) then ',' else '@'}
</div>  

您的输出和查询不匹配。
元素在哪里,而
元素在哪里?对不起,我不知何故错误配置了在线XQuery工具,因此输出是错误的。谢谢你的提示!请给出所需输出的确切示例。非常感谢您花时间更正我的代码(还有很多东西需要学习)!虽然我理解
{string join($bibl/biblScope,,')}@
中发生的事情,但输出仍然不是我想要的,因为现在每个
内容后面都有逗号,每个
内容后面都有“@”。事实上,除了最后一个之外,我想在每个
后面加一个逗号。插入
@
最初是为了测试(对于
表单下的最后一个
,请显示
@
,而不是
)…如果您向我们展示所需的输出,会让我们的生活更轻松。非常感谢Jens给出了一个有效的答案。然而,正如Michael Kay所建议的,我用
$bibl/biblScope/text()替换了第二个FLWOR($biblScope在$bibl/biblScope/text()…
)。我一定会看看您提到的应用程序操作符,因为它使代码更易于阅读。再次感谢您抽出时间!您应该能够使用axis步长,但至少BaseX和eXist DB在这方面存在一些问题。BaseX也收到了一个bug报告,我会尽快处理ExistDB的bug报告。
form/bibl ! <div>
{
  biblScope/text(),
  if (position() ne last()) then ',' else '@'
}
</div>