如何在JavaScript中向JSON数组插入对象(MarkLogic场景)
在MarkLogic中向JSON数组插入新项(避免全量替换)
问题场景
尝试用JavaScript向JSON文档的数组中插入新项,因数据量较大,不想通过xdmp.nodeReplace全量替换数组,但现有代码执行报错。
报错代码
'use strict'; declareUpdate(); xdmp.documentInsert("/test/items.json" , { result: [{"name": "name0"," ref": "000"}]}); let item1 = {"name": "name1"," ref": "111"}; var n1 = new NodeBuilder(); var newNode1 = n1.addNode(item1); var parentNode = cts.doc("/test/items.json"); var resultNode = parentNode.xpath("/result"); xdmp.nodeInsertChild(resultNode, newNode1.toNode()); // 报错信息:XDMP-CHILDUNNAMED: //xdmp.nodeInsertChild(Sequence(xdmp.unpath("fn:doc('/test/items.json')/array-node('result')/object-node()")), ObjectNode({"name":"name1", " ref":"111"})) // -- Object nodes cannot have unnamed children // 尝试过的另一种写法,同样报错 //xdmp.nodeInsertChild(resultNode, newNode1); // 报错信息:XDMP-ARGTYPE: xdmp.nodeInsertChild(Sequence(xdmp.unpath("fn:doc('/test/items.json')/array-node('result')/object-node()")), [object NodeBuilder]) // -- arg2 is not of type Node
期望结果
/test/items.json最终内容:
{ "result": [{"name": "name0"," ref": "000"}, {"name": "name1"," ref": "111"}]}
解决方案
修正后代码
'use strict'; declareUpdate(); // 仅在文档不存在时初始化,避免重复插入 if (!cts.docExists("/test/items.json")) { xdmp.documentInsert("/test/items.json", { result: [{"name": "name0"," ref": "000"}]}); } const item1 = {"name": "name1"," ref": "111"}; // 直接将JS对象转为JSON节点,替代NodeBuilder写法更简洁 const newItemNode = xdmp.toJSON(item1); const doc = cts.doc("/test/items.json"); // 精准获取array-node类型的result数组节点,而非数组内的元素 const resultArrayNode = doc.xpath("/array-node('result')"); // 向数组节点插入新元素节点 xdmp.nodeInsertChild(resultArrayNode, newItemNode);
错误原因说明
- 节点定位错误:原代码中
parentNode.xpath("/result")匹配到的是数组内的object-node(即数组元素),而非数组本身。对象节点不允许添加无名子节点,因此触发XDMP-CHILDUNNAMED错误。需通过/array-node('result')精准定位数组节点。 - 参数类型错误:
xdmp.nodeInsertChild要求第二个参数为节点类型,原代码中直接传入NodeBuilder对象会触发XDMP-ARGTYPE错误,需调用toNode()转换,或直接用xdmp.toJSON()将JS对象转为节点更高效。
内容的提问来源于stack exchange,提问作者Val
相关产品推荐
相关产品推荐

