2017-12-18 3 views
1

Ich habe einen String, der im JSON-Format istIgnorieren Nachschlüssel in JSONObject

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

Wenn ich ein Objekt aus dieser Zeichenfolge

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

ich eine Störung erhalte zu schaffen versuchen

org.json.JSONException: Duplicate key "innerkey1" 

Gibt es eine Möglichkeit, das JSONObject zu erstellen, indem Sie den letzten Schlüssel aus der Zeichenfolge ignorieren?

+2

Mögliches Duplikat von [JSONException doppelte Schlüssel auflösen] (https://stackoverflow.com/questions/4912386/resolve-jsonexception-duplicate-keys) – Lichtbringer

+1

Das JSON sieht seltsam aus. Schlüssel1: Wert1 ist OK, aber dann haben Sie ein Array als Wert; Wo ist der Schlüssel? –

+0

@BuzzMoschetti Jetzt können Sie nach der gültigen JSON-Zeichenfolge suchen. –

Antwort

0

Leider nicht. Es ist zwar technisch nicht gegen JSON-Standards, aber es ist nicht leicht, mit solchen zu arbeiten, und Sie werden kaum eine Bibliothek finden, die es analysieren kann.

Siehe hier: https://stackoverflow.com/a/21833017/8972283

Ich würde empfehlen, zu aktualisieren, wie Sie Ihre JSON, wenn möglich erstellt werden.

1

Dies ist ein Problem der JSON-Spezifikation. Je nachdem, welche Spezifikation verwendet wird, kann man interpretieren, ob doppelte Schlüssel überhaupt zulässig sind. In this thread wurde weitgehend vereinbart, dass die Definition besagt, dass ein Schlüssel in einem JSONObject eindeutig sein muss.

Aus diesem Grund sollten Sie nicht versuchen, ein wahrscheinlich ungültiges JSON-Objekt zu analysieren, sondern ein gültiges zu verwenden.

Aber ich hätte einen kleinen Vorschlag für eine Lösung: Wie auch immer man es in die Praxis umsetzt, könnte man den (mehrfach vorkommenden) Schlüssel verwenden und alle dort gespeicherten Objekte als Array diesem (nun eindeutigen) Schlüssel zuordnen. Sie können also mehrere identische Schlüssel zusammenführen und die verknüpften Objekte zu einem Array zusammenführen. Dies würde zumindest machen das JSON-Objekt gültig:

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

Leider kann ich meine Json-Saite nicht ändern, da ich das von verschiedenen APIs bekomme. –

0

Es ist nicht die einfachste Lösung, aber es ermöglicht Ihnen Duplikate in Ihrer Eingabestring haben und entscheiden, was mit ihnen zu tun (umbenennen, Drop usw.). Sie sollten die Bibliothek Gson verwenden und Ihre eigene TypeAdapter registrieren, die für die Serialisierung/Deserialisierung von Objekten zuständig ist. Es würde wie folgt aussehen:

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

Es war der komplizierteste Teil, jetzt brauchen wir nur die JSON Zeichenfolge zu lesen:

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

Die map nur die erste "innerkey1" enthalten wird.

0

Ich habe eine JSON parser, die die Verwendung von Code erlaubt, doppelte Schlüssel als Elemente in einem Array zu behandeln. Siehe den Abschnitt "Document Builder Code".