JSONiq - 如何将数组转换为序列?

JSONiq - how do you convert an array to a sequence?

使用JSONiq to JavaScript implementation of JSONiq,假设我有一个数组

let $a := [1,2,3]

我想以序列的形式获取元素,但是所有这些 return 数组本身 -

return $a()
return $a[]
return members($a)

提取数组成员的正确方法是什么?


我的最终目标是将数组中的对象转换为字符串,就像这样 -

let $updates := [
  {"address": "%Q0.1", "keys": ["OUT2", "output.2"], "value": 0},
  {"address": "%Q0.7", "keys": ["OUT8", "output.8"], "value": 1}
]

for $update in $updates()
return "<timestamp>|address|" || $update.address

为了将 JSON 对象数组转换为一组字符串,例如 <timestamp>|address|%Q0.7,等等


编辑:使用 Zorba $a() 语法似乎工作正常 - 节点 jsoniq 解析器有问题吗?

例如

jsoniq version "1.0";

let $updates := [
  {"address": "%Q0.1", "keys": ["OUT2", "output.2"], "value": 0},
  {"address": "%Q0.7", "keys": ["OUT8", "output.8"], "value": 1}
]

for $update in $updates()
return current-dateTime() || "|address|" || $update.address

returns

2021-02-19T23:10:13.434273Z|address|%Q0.1 2021-02-19T23:10:13.434273Z|address|%Q0.7

在核心 JSONiq 语法中,一个数组被转换成一个序列(即,它的成员被提取)带有一个空对或方括号,像这样:

$array[]

示例:

[1, 2, 3, 4][]

returns序列:

(1, 2, 3, 4)

这意味着查询将是:

let $updates := [
  {"address": "%Q0.1", "keys": ["OUT2", "output.2"], "value": 0},
  {"address": "%Q0.7", "keys": ["OUT8", "output.8"], "value": 1}
]

for $update in $updates[]
return "<timestamp>|address|" || $update.address

带有一对空括号的类似函数调用的表示法可以追溯到 JSONiq 的早期,因为它主要是作为 XQuery 的扩展而设计的,映射和数组是通过函数调用导航的( $object("foo")$array()$array(2))。然而,随着 JSONiq 开始拥有自己的生命,为 JSON 导航引入了更加用户友好和直观的语法:

$array[[1]]

用于给定位置的数组成员查找

$object.foo

用于给定键的对象查找和

$array[]

用于数组拆箱。

虽然 XQuery 的 JSONiq 扩展仍然存在于用户需要 JSON 和 XML 支持的场景中(并且受 Zorba 3.0、IBM Websphere 等支持) ,核心 JSONiq 语法是所有专门支持 JSON 的引擎的主要语法,例如 Rumble.

一些引擎(包括 Zorba 3.0)同时支持核心 JSONiq 语法和 XQuery 的 JSONiq 扩展,您可以通过语言版本声明选择您想要的:

jsoniq version "1.0";
[1, 2, 3, 4][]

对比

xquery version "3.0";
[1, 2, 3, 4]()

Zorba 相对宽松,甚至可能在其核心 JSONiq 实现中同时接受 () 和 []。

(警告:Zorba 2.9 不支持最新的核心 JSONiq 语法,特别是 try.zorba.io 页面在 Zorba 2.9 上仍然 运行s。您需要下载 Zorba 3.0 和 运行 如果您想在本地使用它)。

最后一点:JSON 导航在数组和对象的序列上也是并行工作的:

(
  {"foo":1},
  {"foo":2},
  {"foo":3},
  {"foo":4}
).foo

returns

(1, 2, 3, 4)

(
  [1, 2],
  [3, 4, 5],
  [6, 7, 8]
)[]

returns

(1, 2, 3, 4, 5, 6, 7, 8)

这使得导航大型序列变得非常容易和紧凑:

$collection.foo[].bar[[1]].foobar[].foo