【问题标题】:Parse long JSON recursively with nested structure by value按值递归解析长 JSON 与嵌套结构
【发布时间】:2015-04-17 21:48:39
【问题描述】:

需要解析每个 id 元素并按值进行比较,当找到元素时 - 抓取所有具有该 id 的块,某种过滤器。

Java 代码:

  public void getBlocksByIds(JsonNode rootNode) throws IOException {

      Iterator<Map.Entry<String,JsonNode>> fields = rootNode.fields();


      while (fields.hasNext()) {        

          Map.Entry<String,JsonNode> field = fields.next();
//          System.out.println(field.getKey() + " = " + field.getValue());      


          if (field.getKey().equals("id") && field.getValue().asText().equals("b3d888b1-c4f0-4337-87a3-d51961d81c0b")) {
            System.out.println("id is found: "+field.getValue().asText());
          } else {                  
            getBlocksByIds(field.getValue());
          }

      }    

  }

带有嵌套子块的 JSON:

{
  "id": "fe13e84e-fa26-46fb-bd39-6b581dad9eb7",
  "type": "data",
  "title": "root",
  "children": [
    {
      "id": "d6426ce9-e243-40b1-93f5-a1aaa3193a4c",
      "type": "group",
      "title": "first",
      "children": [
        {
          "id": "b3d888b1-c4f0-4337-87a3-d51961d81c0b",
          "type": "class",
          "title": "A",
          "children": [
            {
              "id": "df0a218d-7a08-4295-abb7-e0bdfb835414",
              "type": "color",
              "title": "red",
              "children": [
                {
                  "id": "7c451766-5f91-48f5-8db5-868e7cc95905",
                  "type": "taste",
                  "title": "sour",
                  "children": [
                    {
                      "id": "2567b1f1-2662-48fd-a487-167e514ce5d8",
                      "type": "size",
                      "title": "tiny"
                    },
                    {
                      "id": "29a73327-d5be-44cc-8c1d-e45ddb8be2b7",
                      "type": "size",
                      "title": "small"
                    },
                    {
                      "id": "718d54cf-ce19-44e9-9a94-3214ef482dc2",
                      "type": "size",
                      "title": "medium"
                    },
                    {
                      "id": "f1f81f3a-be49-411d-b176-0d1e67f18864",
                      "type": "size",
                      "title": "large"
                    },
                    {
                      "id": "ccbe91ef-7dec-4dc7-bbf5-ef79161670df",
                      "type": "size",
                      "title": "huge"
                    }
                  ]
                },
                {
                  "id": "7b9ae76c-d189-4b44-9ea1-ea38b05d35ae",
                  "type": "taste",
                  "title": "bitter",
                  "children": [
                    {
                      "id": "42b7f578-e907-475d-beb3-d1d53af1bec9",
                      "type": "size",
                      "title": "tiny"
                    },
                    {
                      "id": "acaed672-d5df-43a2-9e30-5cf55f74b1ce",
                      "type": "size",
                      "title": "small"
                    },
                    {
                      "id": "d4785d0b-9116-4361-8349-505934ceb9c9",
                      "type": "size",
                      "title": "medium"
                    },
                    {
                      "id": "7ee5494f-dc36-45e2-bc09-2ac948133523",
                      "type": "size",
                      "title": "large"
                    },
                    {
                      "id": "0ded484b-78f2-497e-bdfe-c9bd2ba78368",
                      "type": "size",
                      "title": "huge"
                    }
                  ]
                },

json 文件可以在这里找到 - https://drive.google.com/file/d/0B3IocxfOfRHodUhWUVRVdC1kVnM/view?usp=sharing

问题是我的递归根本不起作用,例如 json 可能是 1G,所以如果解决方案是某种流式传输,那就太好了。

PS 请不要以这种方式回答 - 这个链接应该有帮助或尝试类似的东西,我已经尝试过 ggl 和自写 - 只有真正的工作样本才会被接受。

提前致谢。

以下是 Karl-Bjørnar Øie 的代码 - 再次感谢 U 的帮助,它需要稍作改进才能解析出之前找到的具有 id 的块的内容以生成此 json 结构:

        {
          "id": "2567b1f1-2662-48fd-a487-167e514ce5d8",
          "type": "size",
          "title": "tiny"
        },
        {
          "id": "29a73327-d5be-44cc-8c1d-e45ddb8be2b7",
          "type": "size",
          "title": "small"
        }


  public JSONArray getIdsByStreaming(List<String> ids) throws IOException, JSONException {

    JsonParser parser = new JsonFactory().createJsonParser(new File("D:\\test.json"));

    JSONArray jsonArr = new JSONArray();

    while (parser.nextToken() != JsonToken.NOT_AVAILABLE) {
      if ("id".equals(parser.getCurrentName())) {
        parser.nextToken();
        String value = parser.getText();

        Iterator<String> it = ids.iterator();
        while (it.hasNext()) {
          if (value.equals(it.next())) {
//            System.out.println("id is found: " + value);

            JSONObject json = new JSONObject();
            json.put("id", value);

            // grab the type
            parser.nextToken();
            parser.nextToken();            
            json.put("type", parser.getText());

            // grab the title
            parser.nextToken();
            parser.nextToken();            
            json.put("title", parser.getText());                        

            jsonArr.put(json);
            it.remove();            
            if (!it.hasNext()) {
//              System.out.println(jsonArr);
              return jsonArr;
            }
          }
        }
      }
    }

    parser.close();
    return jsonArr;
  }

测试:

  public static void main(String[] args) throws IOException, ParseException, JSONException {

    List<String> ids = new ArrayList<>();

    ids.add("b3d888b1-c4f0-4337-87a3-d51961d81c0b");
    ids.add("d6426ce9-e243-40b1-93f5-a1aaa3193a4c");
    ids.add("42b7f578-e907-475d-beb3-d1d53af1bec9");
    ids.add("5d0b1503-74f8-4e62-b501-37ed3c209cc9");
    ids.add("fadef54e-cf5f-4470-a872-b83e39da7a40");

      JsonParseTreeBlocks jptb = new JsonParseTreeBlocks();

      jptb.getIdsByStreaming(ids);

  }

一切都很好,除非我们添加一个不存在的 id - 导致代码无限运行,需要修复。

【问题讨论】:

    标签: java json


    【解决方案1】:

    Jackson JSON 处理器 (http://jackson.codehaus.org/) 具有流式 API (http://wiki.fasterxml.com/JacksonStreamingApi)。对于任何严重的数据大小,这都是可行的方法。

    这是一个例子:

    JsonParser parser = new JsonFactory().createJsonParser(new File("c:\\big.json"));
    while (parser.nextToken() != JsonToken.NOT_AVAILABLE) {
        if ("id".equals(parser.getCurrentName())) {
            parser.nextToken();
            String value = parser.getText();
            if (value.equals("b3d888b1-c4f0-4337-87a3-d51961d81c0b")) {
                System.out.println("id is found: " + value);
            }
        }
    }
    parser.close();
    

    某种流媒体是的,抱歉以这种方式回答。

    【讨论】:

    • 首先 - 感谢您的帮助。正如我在帖子的第一个字符串中所写的那样“抓住所有带有该 id 的块”,这意味着解析该块中的数据以产生类似的结果:`{“id”:“2567b1f1-2662-48fd-a487-167e514ce5d8 ", "type": "size", "title": "tiny" }, { "id": "29a73327-d5be-44cc-8c1d-e45ddb8be2b7", "type": "size", "title": "small " } `
    • 现在它工作正常,除非添加不存在的 id,这会导致长时间搜索和运行 - 需要修复,也许你可以给我一些想法如何解决这个问题?
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-06-28
    • 2020-04-29
    • 1970-01-01
    • 2014-01-05
    • 2017-08-25
    相关资源
    最近更新 更多