MarkLogic查询JSON数组特定值合并销售数据转换为XML的实现问题
MarkLogic JSON文档筛选与XML转换解决方案
需求说明
筛选product数组中包含指定商品的JSON文档,优先使用JavaScript实现,将商品与对应销售数据合并后转换为目标XML格式,要求使用模块化函数实现,避免硬编码。
现有测试文档
/doc1.json
{ "seller": "s1", "product": [ "football", "basketball" ], "sales": [ { "football": 60, "basketball": [ { "c1": 76, "c2": 90 } ] } ] }
/doc2.json
{ "seller": "s2", "product": ["football"], "sales": [ {"football": 80} ] }
已知问题说明
- 原有查询
cts.search(cts.jsonPropertyValueQuery('product', 'football'))返回两个文档属于正常结果,因为两个测试文档的product数组都包含football。如果测试查询basketball,仅会返回/doc1.json,建议添加exact参数确保精确匹配避免误命中。 - 原有转换代码的XPath路径匹配错误,无法正确对应JSON转XML后的节点结构,导致输出结果不符合预期。
实现方案
1. 模块化查询函数
封装可复用的商品查询模块,路径可设为/modules/product-utils.sjs:
/** * 根据商品名称筛选匹配的文档 * @param {string} productName 要查询的商品名称 * @returns {Array} 匹配的文档数组 */ function getDocsByProduct(productName) { const query = cts.jsonPropertyValueQuery('product', productName, 'exact'); return Array.from(cts.search(query)); } /** * 将单篇商品文档转换为目标XML格式 * @param {object} doc MarkLogic文档对象 * @returns {object} 转换后的XML节点 */ function convertToTargetXml(doc) { const docData = doc.toObject(); const salesData = docData.sales[0]; let xmlBuilder = `<root> <products>`; docData.product.forEach(product => { const saleVal = salesData[product]; let saleContent = ''; if (typeof saleVal === 'number') { saleContent = String(saleVal); } else if (Array.isArray(saleVal) && typeof saleVal[0] === 'object') { Object.entries(saleVal[0]).forEach(([key, value]) => { saleContent += ` <${key}>${value}</${key}>`; }); } xmlBuilder += ` <product>${product}<sales>${saleContent}</sales></product>`; }); xmlBuilder += ` </products> </root>`; return fn.head(xdmp.unquote(xmlBuilder)); } module.exports = { getDocsByProduct, convertToTargetXml };
2. 调用示例
// 引入工具模块 const { getDocsByProduct, convertToTargetXml } = require('/modules/product-utils.sjs'); // 示例:查询所有包含football的文档并转换 const matchedDocs = getDocsByProduct('football'); const convertedResults = matchedDocs.map(doc => convertToTargetXml(doc)); // 输出结果 convertedResults.forEach(xmlRes => xdmp.output(xmlRes));
输出结果验证
转换后的结果完全匹配预期:
/doc1.json转换结果
<root> <products> <product>football<sales>60</sales></product> <product>basketball<sales> <c1>76</c1> <c2>90</c2> </sales></product> </products> </root>
/doc2.json转换结果
<root> <products> <product>football<sales>80</sales> </product> </products> </root>
内容的提问来源于stack exchange,提问作者Chris
相关产品推荐
相关产品推荐

