2015-04-17 3 views
-4

Нужно анализировать каждый элемент id и сравнивать его по значению, когда элемент найден - захватить весь блок с этим идентификатором там, какой-то фильтр.Проанализируйте длинный JSON рекурсивно с вложенной структурой по значению

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 и самостоятельно писать - будет принят только настоящий рабочий образец.

Thx заранее.

Ниже приводится код от Karl-Bjørnar Õie - спасибо U за помощь еще раз, что нужно немного улучшений разобрать содержимое блока с идентификатором ранее найденную производить эту 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; 
    } 

Test :

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); 

    } 

Все прекрасно работает, за исключением того, когда мы добавим несуществующий идентификатор - приводит к бесконечно выполнение кода, нужно исправить.

ответ

2

Процессор 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(); 

Своего рода потокового да, извините за ответ таким образом.

+0

Прежде всего - благодарим U за помощь. Как я писал в первой строке сообщения «захватить весь блок с этим идентификатором там», это означает, что нужно проанализировать данные в этом блоке, чтобы получить что-то вроде: ' { « id »:« 2567b1f1-2662-48fd- a487-167e514ce5d8" , "типа": "размер", "название": "крошечные" }, { "идентификатор": "29a73327-d5be-44cc-8c1d-e45ddb8be2b7", "типа": " size ", " title ":" small " } ' –

+0

Теперь он отлично работает, за исключением случаев, когда добавление несуществующего идентификатора, что приводит к длительному поиску и запуску - нужно исправить, может быть, U может дать мне несколько идей о том, как решить это? –

Смежные вопросы