2014-09-28 3 views
3

Использованием простого Json файл, например:Использования Gson с путем

{"menu": { 
    "id": "file", 
    "value": "File", 
    "popup": { 
    "menuitem": [ 
     {"value": "New", "onclick": "CreateNewDoc()"}, 
     {"value": "Open", "onclick": "OpenDoc()"}, 
     {"value": "Close", "onclick": "CloseDoc()"} 
    ] 
    } 
}} 

Я хочу, чтобы иметь возможность получить JsonArray имя menuitem используя путь:

String path = "menu.popup.menuitem" 

Я пытался сделать это с помощью :

public static JsonElement fromString(String json, String path) throws JsonSyntaxException { 
     JsonObject obj = GsonBuilder.create().fromJson(json, JsonObject.class); 
     String[] seg = path.split("."); 
     for (String element : seg) { 
      if (obj != null) { 
       obj = obj.get(element).getAsJsonObject(); 
      } else { 
       return null; 
      } 
     } 
     return obj 
} 

с:

JsonElement jsonElement = fromString(json, path); 

Но когда я попробую isJsonArray(), возвращаемое значение - false. При выполнении дополнительной проверки работоспособности с использованием Gson.toJson(jsonElement) выход представляет собой полную строку json String (выше), которая была введена изначально. Что случилось?

+0

возможно дубликат [струнной расколе Java с "" (точка)] (http://stackoverflow.com/questions/14833008/java-string-split-with-dot) – Devrim

+0

Используйте, например, ';' вместо '.'. –

ответ

3

. Так что для строки, как

"foo" 

"foo".split(".") разделится на f, o, o

"foo" 
^^^ 

означает, что вы получите в результате массив с четырьмя пустыми строками (3 расколы дают 4 элемента).

["", "", "", ""] 

На самом деле я соврал здесь, потому что split(regex) делает еще одну вещь: она удаляет конечные пустые строки из результирующего массива, но ваш массив содержит только пустые строки, а это значит, что все они будут удалены, так split(".") будет возвращать только пустые массив [], поэтому ваш цикл не будет повторяться даже один раз (поэтому ваш метод возвращает немодифицированный obj).

Чтобы избавиться от этой проблемы, вам нужно будет сделать . буквально (вам нужно ее избежать). Для этого вы можете использовать, например, split("\\.") или split("[.]") или split(Pattern.quote("."), которые работают так же, как split("\\Q.\\E") - это добавляет область цитаты.

Также внутри цикла вы должны сначала проверить тип Json, с которым работаете, поскольку getAsJsonObject не будет работать, если Json является массивом. Так что ваш код должен вероятно выглядеть

public static JsonElement fromString(String json, String path) 
     throws JsonSyntaxException { 
    JsonObject obj = new GsonBuilder().create().fromJson(json, JsonObject.class); 
    String[] seg = path.split("\\."); 
    for (String element : seg) { 
     if (obj != null) { 
      JsonElement ele = obj.get(element); 
      if (!ele.isJsonObject()) 
       return ele; 
      else 
       obj = ele.getAsJsonObject(); 
     } else { 
      return null; 
     } 
    } 
    return obj; 
} 
+0

Альтернативно path.split ("[.] ") также можно использовать, как показано в [], изображает буквенный символ. – prash

+0

@prash Да, о чем уже упоминалось в ответе, а также несколько других способов: – Pshemo

+0

Вау такой подробный! .. Извините, я не знаю заметьте, я только что проверил раздел кода .. ty для указания :-) – prash

2

Я не знаю, почему это не встроенный в Gson, но здесь это метод, который я написал, что возвращает JsonElement данный вход JsonElement и JSON Путь:

/** 
* Returns a JSON sub-element from the given JsonElement and the given path 
* 
* @param json - a Gson JsonElement 
* @param path - a JSON path, e.g. a.b.c[2].d 
* @return - a sub-element of json according to the given path 
*/ 
public static JsonElement getJsonElement(JsonElement json, String path){ 

    String[] parts = path.split("\\.|\\[|\\]"); 
    JsonElement result = json; 

    for (String key : parts) { 

     key = key.trim(); 
     if (key.isEmpty()) 
      continue; 

     if (result == null){ 
      result = JsonNull.INSTANCE; 
      break; 
     } 

     if (result.isJsonObject()){ 
      result = ((JsonObject)result).get(key); 
     } 
     else if (result.isJsonArray()){ 
      int ix = Integer.valueOf(key) - 1; 
      result = ((JsonArray)result).get(ix); 
     } 
     else break; 
    } 

    return result; 
} 

назвать, использовать что-то вроде:

String jsonString = ...; 

Gson gson = new Gson(); 
JsonObject jsonObject = gson.fromJson(jsonString, JsonObject.class); 
JsonElement subElement = getJsonElement(jsonObject, "a.b.c[2].d"; 
Смежные вопросы