0

我无法弄清楚如何编写一些 XQuery。我在 MarkLogic 中有一个 JSON 结构,如下所示:

{
    "id": "pres003A10",
    "title": "A Course About Something",
    "description": "This course teaches people about some things they may not know.",
    "author": "A.N. Author",
    "updated": "2007-01-19",
    "decks": [
      {
        "id":"really-basic-stuff",
        "exclude": ["slide3", "slide12"]
      },
      {
        "id":"cleverer-stuff",
        "exclude": []
      }
    ]           
  }

exclude数组包含幻灯片中幻灯片的标识符(演示文稿由一张或多张幻灯片组成)。我正在尝试编写一段代码,它将在该排除列表中查找幻灯片 ID,如果存在则将其删除,如果不存在则将其添加(切换)。

我可以使用以下方法获取数组节点本身:

let $exclude := doc('/presentations/presentation.json')/object-node()/decks[id = 'markup-intro']/array-node('exclude')

但我无法终生看到我如何更新该数组以删除或添加项目。目的是调用一个类似的函数:

local:toggle-slide($presentation) as object-node()
{
   (: xdmp:node-update(...) goes here :)
};

那么,如何更新该数组?

4

2 回答 2

3

在内存中,JSON 节点树(以及 XML 树)是不可变的。

修改一棵树的方法是构造一棵新树,复制未更改的节点,并创建更改后的父节点和祖先节点。

也就是说,有一种更简单的方法来修改 JSON。如果你调用xdmp:from-json()根节点,你会得到一个可变的内存映射/数组结构。

然后,您可以使用map:get()地图上的和数组上的 [ITEM_NUMBER] 导航到数组,并为适当的 json:array 对象删除或插入项目。

完成后,调用xdmp:to-json()将根映射转回节点。

希望有帮助,

于 2017-09-13T23:07:07.720 回答
2

如果需要更新数据库中的 json,可以使用xdmp:node-replace. 使用 node-replace 的问题是,您必须使用命名节点来提供它。为此,您需要将数组节点包装在对象节点中,然后在对象节点中动态抓取数组节点。这是一个工作示例:

xquery version "1.0-ml";

(: insert test data :)
xdmp:document-insert("/presentations/presentation.json", xdmp:unquote('{
    "id": "pres003A10",
    "title": "A Course About Something",
    "description": "This course teaches people about some things they may not know.",
    "author": "A.N. Author",
    "updated": "2007-01-19",
    "decks": [
      {
        "id":"markup-intro",
        "exclude": ["slide3", "slide12"]
      },
      {
        "id":"cleverer-stuff",
        "exclude": []
      }
    ]           
  }'
))
;

(: node-replace array-node :)
let $exclude := doc('/presentations/presentation.json')/object-node()/decks[id = 'markup-intro']/array-node('exclude')
return xdmp:node-replace($exclude, object-node{
  "exclude": array-node{ "other", "slides" }
}/node())
;

(: view if changed :)
doc('/presentations/presentation.json')

注意:考虑查看 MarkLogic 的服务器端 JavaScript (SJS)支持。以这种方式更新 JSON 可能看起来更自然,特别是如果您需要一次性进行多项更改。

于 2017-09-14T07:11:37.147 回答