我使用Defiant.js,您可以使用XPATH表达式查询json数据。现在我想选择搜索结果的根节点。
源代码
var data = [{
"id": 1,
"categories": [{
"id": 1,
"title": "Category1"
}, {
"id": 2,
"title": "Category2"
}]
}, {
"id": 2,
"categories": [{
"id": 1,
"title": "Category1"
}]
}, {
"id": 3,
"categories": [{
"id": 2,
"title": "Category2"
}, {
"id": 3,
"title": "Category3"
}]
}];
var result = JSON.search(data, '//categories[contains(id, "2")]')
使用该表达式,我得到一个包含两个类别对象的数组
[{
"id": 2,
"title": "Category2"
}, {
"id": 2,
"title": "Category2"
}]
但我想获得命中的根对象
[{
"id": 1,
"categories": [{
"id": 1,
"title": "Category1"
}, {
"id": 2,
"title": "Category2"
}]
}, {
"id": 3,
"categories": [{
"id": 2,
"title": "Category2"
}, {
"id": 3,
"title": "Category3"
}]
}]
有可能吗?提前谢谢!
答案 0 :(得分:0)
几乎就是
//*[categories[contains(id, "2")]]
答案 1 :(得分:0)
基本上,有效XML中始终只有一个根节点,选择根应该像选择文档中的第一个节点一样简单:
/*
我认为在使用defiant.js时,相同的概念适用于JSON。始终只有一个JSON对象充当root。
无论如何,如果确实想要从后代节点上下文开始,您可以使用ancestor
轴向上攀爬任意级别的树。假设我们当前处于其中一个后代节点,比如说categories
,你就可以通过这种方式进入根节点:
ancestor::*[not(parent::*)]
基于您的JSON数据的示例如下:
var xpath1 = '//categories[contains(id, "2")]/ancestor::*[not(parent::*)]';
var result1 = JSON.search(data, xpath1)
var xpath2 = '/*[not(parent::*) and .//categories[contains(id, "2")]]';
var result2 = JSON.search(data, xpath2)
更新:
似乎你的意思是" root"在此上下文中是此xpath引用的元素:/*/*
。
如果这是正确的,您可能需要这样的东西(您也可以用缩写版descendant::
替换.//
):
/*/*[descendant::subcategories[contains(id, '4')]]
更一般地说:
/*/*[descendant::{some filter here}]
如果您的过滤器需要包含检查" root"的属性,则可以使用descendant-or-self
代替descendant
。 JSON对象也是:
/*/*[descendant-or-self::{some filter here}]
答案 2 :(得分:0)
不完全清楚,但在我看来
选择带子类别的对象。= 3 OR subcategory.id = 4 AND name = Test2
转换为
//*[name = 'Test2' and category/subcategories/id = '3' or category/subcategories/id = '4']