如何从其路径中获取 JSONObject 中的嵌套值?

Posted

技术标签:

【中文标题】如何从其路径中获取 JSONObject 中的嵌套值?【英文标题】:How can I get a nested value in a JSONObject from its path? 【发布时间】:2017-04-08 13:54:36 【问题描述】:

我正在尝试实现一个函数,给定任何JSONObject 和路径String,将返回与路径对应的对象属性。

例如,给定这个 json:


"name": "John", 
"friends": [
  "name": "Paul",
   "age":42,
  "name": "Peter",
   "age":24
 ],
"address": "city": "London"

getAttribute(jsonObject, "name") 应该返回 "John" getAttribute(jsonObject, "address.city") 应该返回 "London" getAttribute(jsonObject, "friends[0].name") 应该返回 "Paul"

请注意,此 JSON 只是一个示例,jsonObject 没有预定义的结构,可以表示任何有效的 json。

我编写了实现前两种情况的第一个版本,但是处理数组和多级数组"foo[0][0].bar" 给这个函数带来了很多复杂性。

是否有推荐的工具/库/方法从给定“复杂”路径的 JSONObject 获取属性?

【问题讨论】:

nope.... 有很多很多库.. Gson、Jackson 等 请使用 GSON 而不是从路径中获取值,这里您将直接从实体类对象中获取值 @ΦXocę웃Пepeúpaツ:我知道这些库存在,但我找不到如何使用这些库从任意JSONObject 获取属性。如果您知道该怎么做,请随时回答问题! @AmrutBidri:我无法创建类对象,因为 JSON 会动态变化。似乎GSON 没有提供在给定这样的 json 路径的情况下获取属性的解决方案,但如果我错了,请告诉我! @RajeshKushvaha:请解释一下当 JSON 结构随每次调用而变化时我如何使用 POJO。 【参考方案1】:

Stefan Goessner 的 JSONPath standard 涵盖了更复杂的语法,但它也处理“经典 javascript”JSON 路径语法。

使用JayWay's implementation for Java,回答问题很简单:

public String getAttribute(JSONObject json, String path) 
    return JsonPath.read(json.toString(), path);

【讨论】:

【参考方案2】:

如果我正确理解您的问题,您可能已经得到了回答 here

或者,您也可以尝试以下开源库:

https://github.com/jayway/JsonPath

【讨论】:

谢谢!尽管您链接的问题有些不同,但the first answer 暗示了我如何使用杰克逊来解决这个问题。关于 JSONPath,我考虑过它,但它的语法似乎比 javascript 中的“经典”json 路径涵盖的内容要多得多,而且我担心用它解析这些路径时可能会出现问题。 没问题:)。希望对你有帮助 最后 JSONPath 是最好的选择,再次感谢! :) 很高兴它有用!【参考方案3】:

我如何解决问题:

  import io.restassured.path.json.JsonPath;


String  id = JsonPath.given(Myobject).get(path).toString();

使用这个库的好处是,即使你的 path 有数组,它也可以处理 那个

示例:字符串路径="Myobject[0].id"

【讨论】:

【参考方案4】:

以下本机代码可能会对您有所帮助,

function getDeepValue (object, path, defaultValue) 
    let pathTokens = path.split('.')
    let v = object
    for(let p of pathTokens) 
        try 
            v = Object.prototype.hasOwnProperty.call(v,p)?v[p]:defaultValue
         catch (catchedError) 
            v = defaultValue
            break
        
    
    return v



let o = 
    a: 
        b: 
            1:
                x:9
            ,
            c: [x:1,x:2]
        
    


let path = 'a.b.c.1.x'
console.log(getDeepValue(o, path)) // prints 2

【讨论】:

感谢您的建议!但是,这不会涵盖数组引用语法(“a.b[0].c”)的情况,但如果有人想从头开始实现它,这可能是一个很好的起点。【参考方案5】:

您可以使用 GSON 库并将您的 json 字符串解析为 POJO 类。

private final static Gson GSON = new GsonBuilder().create();

public static <T> T fromJSON(String json, Class<T> clazz) 
    try 
        return GSON.fromJson(json, clazz);
     catch (JsonSyntaxException e) 
        LOGGER.warn("Could not deserialize object", e);
    
    return null;

根据您的 JSON 结构设计您的模型类。

【讨论】:

谢谢,但由于没有预定义的结构,我无法创建与之匹配的类。我能做的唯一假设是该对象将是有效的 JSON。 因为正如我的评论所解释的,这并不能回答问题:我无法创建 POJO 类,因为 JSONObject 每次都会代表不同的 JSON 结构。

以上是关于如何从其路径中获取 JSONObject 中的嵌套值?的主要内容,如果未能解决你的问题,请参考以下文章

jsonobject如何获取一个集合里的某个对象所有属性的值

从 Java Android 中的嵌套 JSON 对象获取数据

在Android中解析嵌套的JSONObject [重复]

如何使用键路径从嵌套的字典dart中获取值。

如何使用键路径从嵌套的字典dart中获取值。

如何在获取值之前对JSONObject中的每个元素进行空检查?