2017-12-18 3 views
1
に重複するキーを無視

私はJSON形式である文字列を持っているはJSONObject

私は

try { 
    JSONObject obj = new JSONObject(str); 
} catch(Exception e) { 
    e.printStackTrace(); 
} 

が、私はエラー

に取得しています。この文字列からオブジェクトを作成しようとしています
String str = "{\"innerkey1\":\"innervalue1\", 
\"innerkey2\":\"innervalue2\",\"innerkey1\":\"innervalue3\"}"; 

org.json.JSONException: Duplicate key "innerkey1" 

文字列から最後のキーを無視してJSONObjectを作成する方法はありますか?

+2

[解決するJSONExceptionの重複キー](https://stackoverflow.com/questions/4912386/resolve-jsonexception-duplicate-keys) – Lichtbringer

+1

JSONが奇妙に見えます。 key1:value1はOKですが、配列として値を取得しています。キーはどこですか? –

+0

@BuzzMoschettiここで、有効なjson文字列を探すことができます。 –

答えて

0

残念ながら、これは技術的にJSON標準には反しませんが、簡単に扱えるものではありません。パースできるライブラリを見つけるのは難しいでしょう。

はこちらをご覧ください:https://stackoverflow.com/a/21833017/8972283

私は可能であれば、あなたのJSONが作成されている方法を更新お勧めします。

1

これはJSON仕様の問題です。どちらの仕様が使用されているかに応じて、重複キーが許可されているかどうかを解釈できます。 this threadでは、キーがJSONObject内で一意でなければならないという定義が広く知られています。

このため、おそらく無効なJSONオブジェクトを解析しないでください。有効なものを使用してください。

しかし、あなたはそれを実践していますが、(複数の)キーを使用して、そこに格納されているすべてのオブジェクトをこの(今一意の)キーに配列として割り当てることができます。したがって、いくつかの同一のキーをマージし、リンクされたオブジェクトを配列にマージします。これは、最も簡単な解決策ではありません

{ 
    "a" : "x", 
    "a" : "y" 
} 
// becomes 
{ 
    "a" : ["x", "y"] 
} 
+0

残念ながら、私は別のAPIからこれを取得しているので、私はJson文字列を変更することはできません。 –

0

、それはあなたがあなたの入力文字列内の重複を持っているし、(名前の変更、ドロップなど)、それらをどのように処理するかを選択することができます:これは、少なくともJSONオブジェクトが有効になるだろう。 Gsonライブラリを使用し、オブジェクトのシリアル化/逆シリアル化を担当するTypeAdapterを登録する必要があります。それは次のようになります。

String str = "{\"innerkey1\":\"innervalue1\", \"innerkey2\":\"innervalue2\",\"innerkey1\":\"innervalue3\"}"; 

Type mapType = new TypeToken<Map<String, String>>() {}.getType(); 

Map<String, String> map = new GsonBuilder() 
     .registerTypeAdapter(mapType, new NoDuplicatesAdapter()) 
     .create() 
     .fromJson(str, mapType); 

mapのみ最初"innerkey1"が含まれています:

class NoDuplicatesAdapter extends TypeAdapter<HashMap<String, String>> { 
    @Override 
    public void write(JsonWriter out, HashMap<String, String> value) throws IOException { 
     out.beginObject(); 
     for (Map.Entry<String, String> e: value.entrySet()) { 
      out.name(e.getKey()).value(e.getValue()); 
     } 
     out.endObject(); 
    } 
    @Override 
    public HashMap<String, String> read(JsonReader in) throws IOException { 
     final HashMap<String, String> map = new HashMap<>(); 
     in.beginObject(); 
     while (in.hasNext()) { 
      String name = in.nextName(); 
      // putting value to the map only if this key is not present; 
      // here you can actually find duplicate keys and decide what to do with them 
      map.putIfAbsent(name, in.nextString()); 
     } 
     in.endObject(); 
     return map; 
    } 
} 

をそれは最も複雑な部分だった、今、私たちはJSON文字列を読み込む必要があります。

0

私はJSON parserを持っています。このコードでは、コードを使用して重複キーを配列の要素として扱うことができます。 「ドキュメントビルダコード」の項を参照してください。