2017-10-04 15 views
5

私は非常に複雑な構造を持っています。jsonです。それには多くのarray elementsが含まれ、それらの配列要素には他の配列要素などが含まれています。 以下を参照してくださいjsonツリー構造。json配列全体の要素を検索して更新する方法json全体をトラバースせずに

JSONツリー構造-1:

enter image description here

JSONツリー構造-2:

enter image description here

黄色で上記強調表示され、I値を更新するように「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

コーディングスタイルがほぼ同じであるため、["responseMap"、 "ValueJson"、 "ticketBean_CM"、...、4]に 'for loop'を使用することができます –

+0

私はそれを通過していません、 。 – Punit

+0

構造内には配列の位置や列の名前など、多くの条件があるようです。それは後でそのようなものを必要としないか、またはこれらの配列を頻繁に通過する必要があるような特定の制約ですか?後者については、より簡単にアクセスできるようにオブジェクトを表すJava Beanを作成することをお勧めします。そうでなければ、 "要素長さの要素セクションなど"を繰り返さないように独自の小さなAPIを作成することができます。 – Asoub

答えて

1

使用するライブラリが柔軟であれば、おそらくJsonPathが役に立ちます。

次のコードを使用して「rdKey」とすべての「要素」を更新することができます。

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

"rdKey"のインスタンスを1つだけ更新する必要があります。 – Punit

+0

オブジェクトで変換されたjsonを必要としない場合、Punitの提案は最短です。それ以外の場合は、[Jackson] [1]からObjectMapperを試すことができます – java4fun

+0

残念ですが、前のコメントが不完全です.Jsonのオブジェクトを変換する必要がない場合、Punitの提案は最短です。おそらく、これらのrdKeyだけを変更するフィルタを追加する必要があります。そうでなければ、[Jackson(Example)](http://tutorials.jenkov.com/java-json/jackson-objectmapper.html)からObjectMapperを試すことができますが、そこにはオブジェクトで完全な構造を構築し、それを読んでmake正しい場所で変更し、最後にそれを書き換えます... – java4fun

1

あなたはJSONのトラバースを脱出したいなら、あなたは同じorg.jsonライブラリで利用可能なJSONPointerを、使用することができます。 例えば:

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

JSONPointerによって受け入れられるようにjson文字列を変更したようですが、入力jsonを変更/変更することはできません。これは別のプロセスから取得したものです。あなたのStringクエリで。 – Punit

+0

これはクエリ文字列の単なる例です。それに応じてそれを変更することができます –

関連する問題