数据测试 递归解析 Json,实现生成可视化 Tree+ 快速获取 JsonPath | 京东云技术团队

京东云开发者 · 2023年10月07日 · 最后由 爱摸鱼的小狐狸 回复于 2023年10月07日 · 4765 次阅读

内部平台的一个小功能点的实现过程,分享给大家:

递归解析 Json,可以实现生成可视化 Tree+ 快速获取 JsonPath

步骤:

1.利用 JsonPath 读取根,获取 JsonObject

2.递归层次遍历 JsonObjec,保存结点信息

3.利用 zTree 展示结点为可视化树,点击对应树的结点即可获取对应结点的 JsonPath

1.利用 JsonPath 读取根,获取 JsonObject

示例 Json:

{
  "errorMessage": null,
  "errorCode": null,
  "dates": {
    "tradeAmt": null,
    "riskLevel": "LEVEL30",
    "optSelected": {
      "77": [
        {
          "optionContent": "20-50万元",
          "productCode": null,
          "created": null,
          "optionOrder": null,
          "modified": null,
          "id": 361,
          "optionScore": 8,
          "isInvalid": 1
        }
      ],
      "78": [
        {
          "optionContent": "资产50-500万元,无债务或债务较轻",
          "productCode": null,
          "created": null,
          "optionOrder": null,
          "modified": null,
          "id": 365,
          "optionScore": 6,
          "isInvalid": 1
        }
      ]
    },
    "riskInfoResult": {
      "optLetter": "A",
      "mqOrder": "1",
      "residenceCountryCode": null,
      "taxReason": null,
      "residenceCountryName": null,
      "residenceCountryNameEn": null,
      "countryNameEn": null,
      "taxInfoCode": null,
      "taxInfoIsCompleted": true,
      "taxInfoIsRight": true,
      "countryCode": null,
      "taxId": null,
      "countryName": null,
      "taxReasonInt": null
    },
    "created": 1565654328000,
    "questions": [
      {
        "questionContent": "您的职业?",
        "productCode": null,
        "created": 1498630051000,
        "options": null,
        "questionSource": "BUSINESS",
        "modified": 1498630051000,
        "id": 75,
        "isInvalid": 1,
        "questionType": 1,
        "order": 1
      },
      {
        "questionContent": "您的主要收入来源是?",
        "productCode": null,
        "created": 1498630051000,
        "options": null,
        "questionSource": "BUSINESS",
        "modified": 1498630051000,
        "id": 76,
        "isInvalid": 1,
        "questionType": 1,
        "order": 2
      }
    ],
    "serialCode": "123",
    "isInvalid": 1,
    "expireTime": 1628783999000,
    "productCode": null,
    "modified": 1565654328000,
    "examScore": 56,
    "id": 4564568,
    "results": {
      "77": "361",
      "78": "365"
    },
    "account": "test"
  },
  "status": "SUCCESS"
}


Java 代码:

String jsonStr = "";
Object rootJson = JsonPath.read(jsonStr, "$");


2.递归层次遍历 JsonObjec,保存结点信息

Java 代码

ZTreeNode zTreeNode = new ZTreeNode();
zTreeNode.setId("$");
zTreeNode.setpId("root");
zTreeNode.setName("root");
zTreeNode.setDepth(0);
zTreeNode.setPath("$");
traverseTree(rootJson, zTreeNode, zTreeNodes);


public static void traverseTree(Object rootJson, ZTreeNode zTreeNode, List<ZTreeNode> zTreeNodes) {
    if (rootJson instanceof Map) {
        for (Map.Entry<String, Object> stringObjectEntry : ((Map<String, Object>) rootJson).entrySet()) {
            ZTreeNode zTreeNodeTemp = new ZTreeNode();
            zTreeNodeTemp.setDepth(zTreeNode.getDepth() + 1);
            zTreeNodeTemp.setPath(zTreeNode.getPath() + "." + stringObjectEntry.getKey());
            zTreeNodeTemp.setId(zTreeNodeTemp.getPath());
            zTreeNodeTemp.setName(stringObjectEntry.getKey());
            zTreeNodeTemp.setpId(zTreeNode.getPath());
            zTreeNodes.add(zTreeNodeTemp);
            traverseTree(stringObjectEntry.getValue(), zTreeNodeTemp, zTreeNodes);
        }
    } else if (rootJson instanceof List) {
        List json = (List) rootJson;
        for (int i = 0; i < json.size(); i++) {
            Object obj = json.get(i);
            ZTreeNode zTreeNodeTemp = new ZTreeNode();
            zTreeNodeTemp.setDepth(zTreeNode.getDepth() + 1);
            zTreeNodeTemp.setPath(zTreeNode.getPath() + "[" + i + "]");
            zTreeNodeTemp.setId(zTreeNodeTemp.getPath());
            zTreeNodeTemp.setName(zTreeNode.getName() + "[" + i + "]");
            zTreeNodeTemp.setpId(zTreeNode.getPath());
            zTreeNodes.add(zTreeNodeTemp);
            traverseTree(obj, zTreeNodeTemp, zTreeNodes);
        }
    } else {
        // do nothing
    }
}


3.利用 zTree 展示结点为可视化树,点击对应树的结点即可获取对应结点的 JsonPath

前端代码:

let zTreeObj;
// zTree 的参数配置
let setting = {
    data: {
        simpleData: {
            enable: true
        }
    },
    callback: {
        onClick: zTreeOnClick
    }
};
zTreeObj = $.fn.zTree.init($("#using_json"), setting, zNodes);
zTreeObj.expandAll(true);


4.扩展:将结点信息反向解析

递归解析 zNodes+ 利用 nestable 插件可视化展示,效果如下:

前端代码:

    let detailResult = JSON.parse(zNodes);
    let nestableContent = $('<ol class="dd-list"></ol>');
    let dataId = 0;
// 遍历解析Json
function parseJson(jsonObj, nestableContent, dataId) {
    for (let key in jsonObj) {

        let element = jsonObj[key];
        if (element === null) {
            element = "null";
        }
        if (element.length > 0 && typeof (element) == "object" || typeof (element) == "object") {

            var li = $('<li class="dd-item" data-id="' + dataId + '"></li>');
            $(li).append('                   <div class="dd-handle">' +
                '                       <span class="bg-muted p-xs b-r-sm">' + key + '</span>' +
                '                   </div>').append('<ol class="dd-list"></ol>').appendTo(nestableContent);
            parseJson(element, $(li).children().eq(1), dataId);
        } else {
            dataId++;
            $('<li class="dd-item" data-id="' + dataId + '"></li>').append('                   <div class="dd-handle">' +
                '                       <span class="bg-muted p-xs b-r-sm">' + key + '</span>' + element +
                '                   </div>').appendTo(nestableContent);
        }

    }
}

作者:京东科技 周波

来源:京东云开发者社区 转载请注明来源

共收到 2 条回复 时间 点赞

试试大 json,比如上万行那种。。可能内存会爆。
之前用递归生成 jsonpath 遇到这个问题

python 的有吗?

需要 登录 后方可回复, 如果你还没有账号请点击这里 注册