2017-10-04 37 views
5

我有一个非常复杂的json结构。它包含很多array elements,那些数组元素包含其他数组元素等等。 请看下面的json树形结构。如何检索和更新json数组元素而不遍历整个json

的Json树结构-1:

enter image description here

的Json树结构-2:

enter image description here

如黄色上面所强调的,我要更新的值“rdKey”字段。 我写了下面的代码,它是完美的罚款工作:

String json = "escaped string (as it's a big string, I can't put it here)"; 
JSONObject jsonObj = new JSONObject(json); 

    if (jsonObj.has("responseMap")) { 
     JSONObject responseMap = jsonObj.getJSONObject("responseMap"); 
     if (responseMap.has("ValueJson")) { 
      JSONObject valueJson = responseMap.getJSONObject("ValueJson"); 
      if (valueJson.has("ticketBean_CM")) { 
       JSONObject ticketBean_CM = valueJson.getJSONObject("ticketBean_CM"); 
       if (ticketBean_CM.has("addByGamma")) { 
        String addByGamma = ticketBean_CM.getString("addByGamma"); 
        System.out.println(addByGamma); 

        if (addByGamma.equals("VCE")) { 
         if (responseMap.has("ScreenJson")) { 
          JSONObject screenJson = responseMap.getJSONObject("ScreenJson"); 
          if (screenJson.has("sections")) { 
           JSONArray sectionArray1 = screenJson.getJSONArray("sections"); 
           if (sectionArray1.length() > 0) { 
            JSONObject section0 = sectionArray1.getJSONObject(0); 
            if (section0.has("sections")) { 
             JSONArray sectionArray2 = section0.getJSONArray("sections"); 
             if (sectionArray2.length() > 3) { 
              JSONObject section6 = sectionArray2.getJSONObject(3); 
              if (section6.has("sections")) { 
               JSONArray sectionArray3 = section6.getJSONArray("sections"); 
               if (sectionArray3.length() > 1) { 
                JSONObject section8 = sectionArray3.getJSONObject(1); 
                if (section8.has("elements")) { 
                 JSONArray elementsArray1 = section8 
                   .getJSONArray("elements"); 
                 if (elementsArray1.length() > 0) { 
                  JSONObject elements1 = elementsArray1.getJSONObject(0); 
                  if (elements1.has("elements")) { 
                   JSONArray elementsArray2 = elements1 
                     .getJSONArray("elements"); 
                   if (elementsArray2.length() > 4) { 
                    JSONObject elements2 = elementsArray2 
                      .getJSONObject(4); 
                    if (elements2.has("rdKey")) { 
                     System.out.println(
                       elements2.getString("rdKey")); 
                     elements2.put("rdKey", 
                       "CircuitID(FullPartial)"); 
                     System.out.println(
                       elements2.getString("rdKey")); 
                     System.out.println(jsonObj.toString()); 
                    } 
                   } 
                  } 
                 } 
                } 
               } 
              } 
             } 
            } 
           } 
          } 
         } 
        } 
       } 
      } 
     } 
    } 

我希望你们帮我,如果有这方面的任何更好的解决方案。我可以在没有遍历整个json对象的情况下执行操作(直到找到相关字段)?如果json树结构发生变化,此解决方案将不起作用,它需要是静态的,作为此代码的成功场景。

请建议更好的解决方案。

+0

因为你的编码风格几乎相同,所以你可以使用'for loop'作为[“responseMap”,“ValueJson”,“ticketBean_CM”,...,4] –

+0

我没有通过它,请你帮忙。 – Punit

+0

看起来你的结构中有很多条件(比如数组中的位置和一些列名)。它是一个特定的约束,就像你以后不需要类似的东西,或者你需要经常通过这些数组?对于后者,我建议创建表示您的对象的Java bean以便于访问。否则,您可以创建自己的小API以避免重复“如果元素等等”。 – Asoub

回答

1

如果您可以灵活使用什么库,那么JsonPath可能对您有用。

您可以更新所有“元素”与“rdKey”使用下面的代码:

JsonPath.parse(json).set("$..elements[?(@.rdKey)].rdKey", "CircuitID(FullPartial)").json() 
+0

我需要只更新“rdKey”的单个实例并非全部。 – Punit

+0

如果你不需要在对象中转换json,Punit的建议是最短的。否则,您可以使用[Jackson]的ObjectMapper [1] – java4fun

+0

对不起,以前的评论是不完整的:如果您不需要在对象中转换json,则Punit的建议是最短的。可能你必须添加一些过滤器来改变你只能使用这些rdKey。否则你可以用[Jackson(Example)](http://tutorials.jenkov.com/java-json/jackson-objectmapper.html)中的ObjectMapper尝试,但是你必须用对象构建完整的结构,读取它,使在正确的地方更改,并在最后重写它... – java4fun

1

如果你想逃离JSON的穿越,那么你可以使用JSONPointer,可以在同一org.json库。 例如: -

String query = <json_pointer_query to element array> 
JSONPointer pointer = new JSONPointer(query); 
JSONObject elementsArrayJSON = (JSONObject) pointer.queryFrom(jsonObj); 
elementsArrayJSON.put("rdKey","CircuitID(FullPartial)"); 

JSON指针查询语言可以被称为:

https://tools.ietf.org/html/rfc6901

注: JSON指针是非常基本的,它不支持通配符。所以你需要确定元素名称,否则会抛出异常。

+0

看来你已经修改了json字符串,以便它被JSONPointer接受,但我不能修改/修改输入json,这是我从另一个进程获得的。在你的String查询中。 – Punit

+0

这只是查询字符串的一个例子,您可以相应地修改它 –