Js解析Json数据获取元素JsonPath与深度

1,810 阅读4分钟

原文出处www.yund.tech/zdetail.htm…

作者: jstarseven


JsonPath 是一种信息抽取类库,是从JSON文档中抽取指定信息的工具,提供多种语言实现版本,包括:Javascript, Python, PHP 和 Java,JsonPath 对于 JSON 来说,相当于 XPATH 对于 XML。

  • JsonPath与Xpath用法对比
  • Java使用Jsonpath解析json数据
  • Js获取Json每个节点的JsonPath
  • 将输出结果转换成树形结构

1.JsonPath与Xpath用法对比

XPath JSONPath 描述
/ $ 根节点
. @ 现行节点
/ .or[] 取子节点
.. n/a 取父节点,Jsonpath未支持
// .. 就是不管位置,选择所有符合条件的条件
* * 匹配所有元素节点
@ n/a 根据属性访问,Json不支持,因为Json是个Key-value递归结构,不需要。
[] [] 迭代器标示(可以在里边做简单的迭代操作,如数组下标,根据内容选值等)
| [,] 支持迭代器中做多选。
[] ?() 支持过滤操作.
n/a () 支持表达式计算
() n/a 分组,JsonPath不支持

2.Java使用Jsonpath解析json数据

1)引入fastjson依赖

<dependency>
        <groupId>com.alibaba</groupId>
        <artifactId>fastjson</artifactId>
        <version>1.2.6</version>
</dependency>

2)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']"));
    }

3.Js获取Json每个节点的JsonPath

1)准备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: '动作电影'
                    }
                ]
            }
        ]
    }

2)遍历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;
    }

3)测试输出

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
    }
]

4.将输出结果转换成树形结构

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
            }
        ]
    }
]

![file](https://p1-jj.byteimg.com/tos-cn-i-t2oaga2asx/gold-user-assets/2020/3/24/1710a4c205eeec19~tplv-t2oaga2asx-image.image)

本文由博客群发一文多发等运营工具平台 OpenWrite 发布