JsonPath 是一種信息抽取類庫,是從JSON文檔中抽取指定信息的工具,提供多種語言實現版本,包括:Javascript, Python, PHP 和 Java,JsonPath 對於 JSON 來說,相當於 XPATH 對於 XML。
(一)JsonPath與Xpath用法對比
(二)Java使用Jsonpath解析json數據
(三)Js獲取Json每個節點的JsonPath
(四)將輸出結果轉換成樹形結構
JsonPath與Xpath用法對比
XPath | JSONPath | 描述 |
---|---|---|
/ | $ | 根節點 |
. | @ | 現行節點 |
/ | .or[] | 取子節點 |
.. | n/a | 取父節點,Jsonpath未支持 |
// | .. | 就是不管位置,選擇所有符合條件的條件 |
* | * | 匹配所有元素節點 |
@ | n/a | 根據屬性訪問,Json不支持,因為Json是個Key-value遞歸結構,不需要。 |
[] | [] | 迭代器標示(可以在里邊做簡單的迭代操作,如數組下標,根據內容選值等) |
| | [,] | 支持迭代器中做多選。 |
[] | ?() | 支持過濾操作. |
n/a | () | 支持表達式計算 |
() | n/a | 分組,JsonPath不支持 |
Java使用Jsonpath解析json數據
引入fastjson依賴
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>fastjson</artifactId>
<version>1.2.6</version>
</dependency>
java簡單的解析案例
public class JsonPath {
public static void main(String[] args) {
String jsonStr = "{\n" +
" \"store\": {\n" +
" \"book\": [\n" +
" {\n" +
" \"category\": \"reference\",\n" +
" \"author\": \"Nigel Rees\",\n" +
" \"title\": \"Sayings of the Century\",\n" +
" \"price\": 8.95\n" +
" },\n" +
" {\n" +
" \"category\": \"fiction\",\n" +
" \"author\": \"Evelyn Waugh\",\n" +
" \"title\": \"Sword of Honour\",\n" +
" \"price\": 12.99,\n" +
" \"isbn\": \"0-553-21311-3\"\n" +
" }\n" +
" {\n" +
" \"category\": \"fiction\",\n" +
" \"author\": \"Evelyn Waugh\",\n" +
" \"title\": \"Sword of Honour two\",\n" +
" \"price\": 12.99,\n" +
" \"isbn\": \"0-553-21311-3\"\n" +
" }\n" +
" ],\n" +
" \"bicycle\": {\n" +
" \"color\": \"red\",\n" +
" \"price\": 19.95\n" +
" }\n" +
" }\n" +
"}";
JSONObject jsonObject = JSON.parseObject(jsonStr);
System.out.println("Book:" + JSONPath.eval(jsonObject, "$.store.book"));
System.out.println("Book數目:" + JSONPath.eval(jsonObject, "$.store.book.size()"));
System.out.println("第一本書title:" + JSONPath.eval(jsonObject, "$.store.book[0].title"));
System.out.println("price大於10元的book:" + JSONPath.eval(jsonObject, "$.store.book[price > 10]"));
System.out.println("price大於10元的title:" + JSONPath.eval(jsonObject, "$.store.book[price > 10][0].title"));
System.out.println("price大於10元的title:" + JSONPath.eval(jsonObject, "$.store.book[price > 10][1].title"));
System.out.println("category(類別)為fiction(小說)的book:" + JSONPath.eval(jsonObject, "$.store.book[category = 'fiction']"));
System.out.println("bicycle的所有屬性值" + JSONPath.eval(jsonObject, "$.store.bicycle.*"));
System.out.println("bicycle的color和price屬性值" + JSONPath.eval(jsonObject, "$.store.bicycle['color','price']"));
}
Js獲取Json每個節點的JsonPath
准備json測試數據
var root = {
name: '測試節點',
doms: {
name: "dom測試",
children: [
{
name: '茶館',
val: 'demo',
child: [
{"name": "李四", "cal": "ceshi"}, {"name": "王五", "cal": "ceshi"}
]
},
{
name: '紅與黑',
val: 'demo',
child: [
{"name": "張三", "cal": "ceshi"}, {"name": "張三", "cal": "ceshi"}
]
}
]
},
children: [
{
name: '學習',
children: []
},
{
name: '電影',
children: [
{
name: '喜劇電影'
},
{
name: '動作電影'
}
]
}
]
}
遍歷Json對象獲取每個節點的深度與JsonPath
function traverseTree(node, flat) {
var stack = [], res = [];
if (!node) return;
stack.push({"dom": node, "dep": 0, "path": "$", "name": "根節點"});
var tmpNode;
while (stack.length > 0) {
tmpNode = stack.pop();
res.push({
"name": tmpNode.name,
"pid": tmpNode.pid,
"path": tmpNode.path,
"dep": tmpNode.dep
});
traverseNode2(tmpNode, tmpNode.dep);
}
// 遍歷單個節點
function traverseNode2(node, dep) {
var doc = node.dom;
if (Object.prototype.toString.call(doc) === '[object Object]') {
for (var val in doc) {
var cpath = (node.path + "." + val);
stack.push({
"dom": doc[val],
"dep": (dep + 1),
"path": cpath,
"pid": node.path,
"name": val
});
}
}
if (Object.prototype.toString.call(doc) === '[object Array]') {
for (let i = 0; i < doc.length; i++) {
stack.push({
"dom": doc[i],
"dep": (dep + 1),
"path": (node.path + "[" + i + "]"),
"pid": node.path,
"name": node.name + "[" + i + "]"
});
}
}
}
// 樹形結構轉換
function flat2tree(jsonData) {
var result = [], temp = {}, i = 0, j = 0, len = jsonData.length;
for (; i < len; i++)
temp[jsonData[i]['path']] = jsonData[i]
for (; j < len; j++) {
var cel = jsonData[j]
var tcel = temp[cel['pid']]
if (tcel) {
if (!tcel['children']) {
tcel['children'] = [];
}
tcel['children'].push(cel)
} else {
result.push(cel);
}
}
return result;
}
return flat ? flat2tree(res) : res;
}
測試輸出
console.log("res-tree:\n" + JSON.stringify(traverseTree(root, false)));
res-tree:
[
{
"name":"根節點",
"path":"$",
"dep":0
},
{
"name":"children",
"pid":"$",
"path":"$.children",
"dep":1
},
{
"name":"children[1]",
"pid":"$.children",
"path":"$.children[1]",
"dep":2
},
{
"name":"children",
"pid":"$.children[1]",
"path":"$.children[1].children",
"dep":3
},
{
"name":"children[1]",
"pid":"$.children[1].children",
"path":"$.children[1].children[1]",
"dep":4
},
{
"name":"name",
"pid":"$.children[1].children[1]",
"path":"$.children[1].children[1].name",
"dep":5
},
{
"name":"children[0]",
"pid":"$.children[1].children",
"path":"$.children[1].children[0]",
"dep":4
},
{
"name":"name",
"pid":"$.children[1].children[0]",
"path":"$.children[1].children[0].name",
"dep":5
},
{
"name":"name",
"pid":"$.children[1]",
"path":"$.children[1].name",
"dep":3
},
{
"name":"children[0]",
"pid":"$.children",
"path":"$.children[0]",
"dep":2
},
{
"name":"children",
"pid":"$.children[0]",
"path":"$.children[0].children",
"dep":3
},
{
"name":"name",
"pid":"$.children[0]",
"path":"$.children[0].name",
"dep":3
},
{
"name":"doms",
"pid":"$",
"path":"$.doms",
"dep":1
},
{
"name":"children",
"pid":"$.doms",
"path":"$.doms.children",
"dep":2
},
{
"name":"children[1]",
"pid":"$.doms.children",
"path":"$.doms.children[1]",
"dep":3
},
{
"name":"child",
"pid":"$.doms.children[1]",
"path":"$.doms.children[1].child",
"dep":4
},
{
"name":"child[1]",
"pid":"$.doms.children[1].child",
"path":"$.doms.children[1].child[1]",
"dep":5
},
{
"name":"cal",
"pid":"$.doms.children[1].child[1]",
"path":"$.doms.children[1].child[1].cal",
"dep":6
},
{
"name":"name",
"pid":"$.doms.children[1].child[1]",
"path":"$.doms.children[1].child[1].name",
"dep":6
},
{
"name":"child[0]",
"pid":"$.doms.children[1].child",
"path":"$.doms.children[1].child[0]",
"dep":5
},
{
"name":"cal",
"pid":"$.doms.children[1].child[0]",
"path":"$.doms.children[1].child[0].cal",
"dep":6
},
{
"name":"name",
"pid":"$.doms.children[1].child[0]",
"path":"$.doms.children[1].child[0].name",
"dep":6
},
{
"name":"val",
"pid":"$.doms.children[1]",
"path":"$.doms.children[1].val",
"dep":4
},
{
"name":"name",
"pid":"$.doms.children[1]",
"path":"$.doms.children[1].name",
"dep":4
},
{
"name":"children[0]",
"pid":"$.doms.children",
"path":"$.doms.children[0]",
"dep":3
},
{
"name":"child",
"pid":"$.doms.children[0]",
"path":"$.doms.children[0].child",
"dep":4
},
{
"name":"child[1]",
"pid":"$.doms.children[0].child",
"path":"$.doms.children[0].child[1]",
"dep":5
},
{
"name":"cal",
"pid":"$.doms.children[0].child[1]",
"path":"$.doms.children[0].child[1].cal",
"dep":6
},
{
"name":"name",
"pid":"$.doms.children[0].child[1]",
"path":"$.doms.children[0].child[1].name",
"dep":6
},
{
"name":"child[0]",
"pid":"$.doms.children[0].child",
"path":"$.doms.children[0].child[0]",
"dep":5
},
{
"name":"cal",
"pid":"$.doms.children[0].child[0]",
"path":"$.doms.children[0].child[0].cal",
"dep":6
},
{
"name":"name",
"pid":"$.doms.children[0].child[0]",
"path":"$.doms.children[0].child[0].name",
"dep":6
},
{
"name":"val",
"pid":"$.doms.children[0]",
"path":"$.doms.children[0].val",
"dep":4
},
{
"name":"name",
"pid":"$.doms.children[0]",
"path":"$.doms.children[0].name",
"dep":4
},
{
"name":"name",
"pid":"$.doms",
"path":"$.doms.name",
"dep":2
},
{
"name":"name",
"pid":"$",
"path":"$.name",
"dep":1
}
]
將輸出結果轉換成樹形結構
console.log("res-tree:\n" + JSON.stringify(traverseTree(root, true)));
res-tree:
[
{
"name":"根節點",
"path":"$",
"dep":0,
"children":[
{
"name":"children",
"pid":"$",
"path":"$.children",
"dep":1,
"children":[
{
"name":"children[1]",
"pid":"$.children",
"path":"$.children[1]",
"dep":2,
"children":[
{
"name":"children",
"pid":"$.children[1]",
"path":"$.children[1].children",
"dep":3,
"children":[
{
"name":"children[1]",
"pid":"$.children[1].children",
"path":"$.children[1].children[1]",
"dep":4,
"children":[
{
"name":"name",
"pid":"$.children[1].children[1]",
"path":"$.children[1].children[1].name",
"dep":5
}
]
},
{
"name":"children[0]",
"pid":"$.children[1].children",
"path":"$.children[1].children[0]",
"dep":4,
"children":[
{
"name":"name",
"pid":"$.children[1].children[0]",
"path":"$.children[1].children[0].name",
"dep":5
}
]
}
]
},
{
"name":"name",
"pid":"$.children[1]",
"path":"$.children[1].name",
"dep":3
}
]
},
{
"name":"children[0]",
"pid":"$.children",
"path":"$.children[0]",
"dep":2,
"children":[
{
"name":"children",
"pid":"$.children[0]",
"path":"$.children[0].children",
"dep":3
},
{
"name":"name",
"pid":"$.children[0]",
"path":"$.children[0].name",
"dep":3
}
]
}
]
},
{
"name":"doms",
"pid":"$",
"path":"$.doms",
"dep":1,
"children":[
{
"name":"children",
"pid":"$.doms",
"path":"$.doms.children",
"dep":2,
"children":[
{
"name":"children[1]",
"pid":"$.doms.children",
"path":"$.doms.children[1]",
"dep":3,
"children":[
{
"name":"child",
"pid":"$.doms.children[1]",
"path":"$.doms.children[1].child",
"dep":4,
"children":[
{
"name":"child[1]",
"pid":"$.doms.children[1].child",
"path":"$.doms.children[1].child[1]",
"dep":5,
"children":[
{
"name":"cal",
"pid":"$.doms.children[1].child[1]",
"path":"$.doms.children[1].child[1].cal",
"dep":6
},
{
"name":"name",
"pid":"$.doms.children[1].child[1]",
"path":"$.doms.children[1].child[1].name",
"dep":6
}
]
},
{
"name":"child[0]",
"pid":"$.doms.children[1].child",
"path":"$.doms.children[1].child[0]",
"dep":5,
"children":[
{
"name":"cal",
"pid":"$.doms.children[1].child[0]",
"path":"$.doms.children[1].child[0].cal",
"dep":6
},
{
"name":"name",
"pid":"$.doms.children[1].child[0]",
"path":"$.doms.children[1].child[0].name",
"dep":6
}
]
}
]
},
{
"name":"val",
"pid":"$.doms.children[1]",
"path":"$.doms.children[1].val",
"dep":4
},
{
"name":"name",
"pid":"$.doms.children[1]",
"path":"$.doms.children[1].name",
"dep":4
}
]
},
{
"name":"children[0]",
"pid":"$.doms.children",
"path":"$.doms.children[0]",
"dep":3,
"children":[
{
"name":"child",
"pid":"$.doms.children[0]",
"path":"$.doms.children[0].child",
"dep":4,
"children":[
{
"name":"child[1]",
"pid":"$.doms.children[0].child",
"path":"$.doms.children[0].child[1]",
"dep":5,
"children":[
{
"name":"cal",
"pid":"$.doms.children[0].child[1]",
"path":"$.doms.children[0].child[1].cal",
"dep":6
},
{
"name":"name",
"pid":"$.doms.children[0].child[1]",
"path":"$.doms.children[0].child[1].name",
"dep":6
}
]
},
{
"name":"child[0]",
"pid":"$.doms.children[0].child",
"path":"$.doms.children[0].child[0]",
"dep":5,
"children":[
{
"name":"cal",
"pid":"$.doms.children[0].child[0]",
"path":"$.doms.children[0].child[0].cal",
"dep":6
},
{
"name":"name",
"pid":"$.doms.children[0].child[0]",
"path":"$.doms.children[0].child[0].name",
"dep":6
}
]
}
]
},
{
"name":"val",
"pid":"$.doms.children[0]",
"path":"$.doms.children[0].val",
"dep":4
},
{
"name":"name",
"pid":"$.doms.children[0]",
"path":"$.doms.children[0].name",
"dep":4
}
]
}
]
},
{
"name":"name",
"pid":"$.doms",
"path":"$.doms.name",
"dep":2
}
]
},
{
"name":"name",
"pid":"$",
"path":"$.name",
"dep":1
}
]
}
]
原文出處:http://www.yund.tech/zdetail.html?type=1&id=c2b21696839eccdef2e9b085b9e064f6
作者: jstarseven