使用Gson与路径 [英] Using Gson with a path

查看:124
本文介绍了使用Gson与路径的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

使用简单的Json文件例如:

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

我想能够通过路径获取名为 menuitem JsonArray

  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字符串(上图)。
出了什么问题?

解决方案

split 找到应该拆分字符串的地方,但是正则表达式中的是特殊字符,它表示在分隔符旁边的任何字符,这意味着您实际上在分割每个字符。所以对于像

这样的字符串
$ b $

 foo

foo.split(。)会分割在 f o o

 foo
^^^

这意味着您会得到结果包含四个空字符串的数组(3个分割包含4个元素)。

  [,,,] 

其实我在这里撒谎是因为 split(regex)还有一件事:它从结果数组中删除尾随的空字符串,但是你的数组只包含空字符串,这意味着它们全部被删除,所以 split(。)将只返回空数组 [] ,所以你的循环不会迭代一次(这就是为什么你的方法返回未修改 obj 文字(你需要转义)。 它)。为此,您可以使用例如 split(\\\。) split([。]) split(Pattern.quote(。),它与 split(\\ Q. \\ E) - 它增加了引用区域。



在循环内部,你应该首先检查你正在处理的Json类型,因为<$ c $如果Json是数组,那么c> getAsJsonObject 将会失败,所以你的代码应该看起来像

  public static JsonElement fromString(String json,String path)
throws JsonSyntaxException {
JsonObject obj = new GsonBuilder()。create()。fromJson(json,JsonObject.class);
String [] seg = (元素:seg){
if(obj!= null){
JsonElement ele = obj.get(element) ;
if(!ele.isJsonObject())
return ele;
else
obj = ele.getAsJsonObject();
} else {
返回null;
}
}
return obj;
}


Using a simple Json file e.g:

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

I want to be able to get the JsonArray named menuitem using a path:

String path =  "menu.popup.menuitem"

I tried to do this using:

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
}

with:

JsonElement jsonElement = fromString(json, path);

But when I try isJsonArray() the return value is false. When doing the extra sanity check using Gson.toJson(jsonElement) the output is the full json String (above) that was inputted originally. What's going wrong?

解决方案

split uses regex to find places on which string should be split, but . in regex is special character which represents "any character beside line separators", which means that you are actually splitting on each character. So for string like

"foo"

"foo".split(".") will split on f, o, o

"foo"
 ^^^

which means you will get as result array with four empty strings (3 splits give 4 elements).

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

Actually I lied here because split(regex) does one additional thing: it removes trailing empty strings from result array, but your array contains only empty strings, which means that they will all be removed, so split(".") will return just empty array [] so your loop will not iterate even once (that is why your method returns unmodified obj).

To get rid of this problem you will need to make . literal (you need to escape it). To do so you can use for instance split("\\.") or split("[.]") or split(Pattern.quote(".") which work same as split("\\Q.\\E") - it adds quotation area.

Also inside loop you should first check type of Json you are handling, because getAsJsonObject will fail if Json is array. So your code should probably look like

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

这篇关于使用Gson与路径的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆