【问题标题】:Basic use of JSONPath in JavaJava中JSONPath的基本使用
【发布时间】:2014-08-16 05:50:14
【问题描述】:

我将 JSON 作为字符串,将 JSONPath 作为字符串。我想用 JSON 路径查询 JSON,得到结果 JSON 作为字符串。

我收集到 Jayway's json-path is the standard。然而,online APIactual library you get from Maven 没有太大的关系。 GrepCode's version 大致匹配。

看来我应该可以做到:

String originalJson; //these are initialized to actual data
String jsonPath;
String queriedJson = JsonPath.<String>read(originalJson, jsonPath);

问题在于 read 根据 JSONPath 实际找到的内容返回它认为最合适的任何内容(例如 List&lt;Object&gt;Stringdouble 等),因此我的代码肯定会抛出异常查询。假设有某种方法可以查询 JSON 并取回 JSON,这似乎是很合理的。有什么建议吗?

【问题讨论】:

  • 我不知道 JSONPath,但我怀疑您链接为“在线 API”的内容是 Jayway 库的官方 API。反正看起来像JavaDoc,不如直接下载最新版本的JavaDoc直接阅读当前的JavaDoc?
  • 我有,大致匹配GrepCode版本。 (我试图让人们更容易查看 API,而无需在任何地方下载库)总体而言,该库的文档很差,但我正在尝试做的事情似乎很基础,以至于我认为它必须有可能。
  • 从当前的 GrepCode 版本看来,应用的过滤器解析 JSON 并返回适当的内容。如果您想要返回 JSON,也许您可​​以提供自己的过滤器,以某种方式使用配置,或者可能只是获取结果并使用 JSONPath 配置使用的相同 JsonProvider 将其转换回 JSON,即类似于 String json = provider.toJson(jsonPath.read(...))

标签: java json jsonpath


【解决方案1】:

对于那些想知道为什么这些多年的答案不起作用的人,您可以从test cases 中学到很多东西。

截至 2018 年 9 月,以下是获取 Jackson JsonNode 结果的方法:

Configuration jacksonConfig = Configuration.builder()
                              .mappingProvider( new JacksonMappingProvider() )
                              .jsonProvider( new JacksonJsonProvider() )
                              .build();

JsonNode node = JsonPath.using( jacksonConfig ).parse(jsonString);

【讨论】:

    【解决方案2】:

    查看 jpath API。它相当于 JSON 数据的 xpath。您可以通过提供将遍历 JSON 数据并返回请求值的 jpath 来读取数据。

    这个 Java 类是实现,它有关于如何调用 API 的示例代码。

    https://github.com/satyapaul/jpath/blob/master/JSONDataReader.java

    自述文件 -

    https://github.com/satyapaul/jpath/blob/master/README.md

    【讨论】:

    • 欢迎提供解决方案的链接,但请确保您的答案在没有它的情况下有用:add context around the link 这样您的其他用户就会知道它是什么以及为什么会出现,然后引用最相关的内容您链接到的页面的一部分,以防目标页面不可用。 Answers that are little more than a link may be deleted.
    • 添加了附加信息。我认为代码非常直接且不言自明。此外,自述文件也有解释和一些例子。我避免复制这些内容。无论如何谢谢!
    【解决方案3】:

    jayway JsonPath 找到的Java JsonPath API 可能会因为上述所有答案/cmets 发生了一些变化。文档也是。只需按照上面的链接阅读README.md,它包含一些非常清晰的IMO使用文档。

    基本上,从当前最新版本的库 2.2.0 开始,有几种不同的方法可以实现这里所要求的,例如:

    Pattern:
    --------
    String json = "{...your JSON here...}";
    String jsonPathExpression = "$...your jsonPath expression here..."; 
    J requestedClass = JsonPath.parse(json).read(jsonPathExpression, YouRequestedClass.class);
    
    Example:
    --------
    // For better readability:  {"store": { "books": [ {"author": "Stephen King", "title": "IT"}, {"author": "Agatha Christie", "title": "The ABC Murders"} ] } }
    String json = "{\"store\": { \"books\": [ {\"author\": \"Stephen King\", \"title\": \"IT\"}, {\"author\": \"Agatha Christie\", \"title\": \"The ABC Murders\"} ] } }";
    String jsonPathExpression = "$.store.books[?(@.title=='IT')]"; 
    JsonNode jsonNode = JsonPath.parse(json).read(jsonPathExpression, JsonNode.class);
    

    作为参考,调用 'JsonPath.parse(..)' 将返回一个类 'JsonContent' 的对象,实现一些接口,例如 'ReadContext',其中包含几个不同的 'read(..)'操作,例如上面演示的操作:

    /**
     * Reads the given path from this context
     *
     * @param path path to apply
     * @param type    expected return type (will try to map)
     * @param <T>
     * @return result
     */
    <T> T read(JsonPath path, Class<T> type);
    

    希望这对任何人都有帮助。

    【讨论】:

    • 这里的 JsonPath.parse().read() 语法对我有用,而上面答案中的代码失败了。感谢发帖!
    【解决方案4】:

    肯定存在一种查询 Json 并使用 JsonPath 取回 Json 的方法。 请参见下面的示例:

     String jsonString = "{\"delivery_codes\": [{\"postal_code\": {\"district\": \"Ghaziabad\", \"pin\": 201001, \"pre_paid\": \"Y\", \"cash\": \"Y\", \"pickup\": \"Y\", \"repl\": \"N\", \"cod\": \"Y\", \"is_oda\": \"N\", \"sort_code\": \"GB\", \"state_code\": \"UP\"}}]}";
     String jsonExp = "$.delivery_codes";
     JsonNode pincodes = JsonPath.read(jsonExp, jsonString, JsonNode.class);
     System.out.println("pincodesJson : "+pincodes);
    

    上面的输出将是内部Json。

    [{"postal_code":{"district":"Ghaziabad","pin":201001,"pre_paid":"Y","cash":"Y","pickup":"Y","re​​pl ":"N","cod":"Y","is_oda":"N","sort_code":"GB","state_code":"UP"}}]

    现在可以通过迭代我们上面得到的 List (JsonNode) 来解析每个单独的名称/值对。

    for(int i = 0; i< pincodes.size();i++){
        JsonNode node = pincodes.get(i);
        String pin = JsonPath.read("$.postal_code.pin", node, String.class);
        String district = JsonPath.read("$.postal_code.district", node, String.class);
        System.out.println("pin :: " + pin + " district :: " + district );
    }
    

    输出将是:

    pin :: 201001 区 :: Ghaziabad

    根据您尝试解析的 Json,您可以决定是获取 List 还是仅获取单个 String/Long 值。

    希望它有助于解决您的问题。

    【讨论】:

    • 您使用的是哪个版本?我在 2.2.0 版本中没有看到任何接受 JsonNode 参数的 read() 方法
    • 我也在尝试同样的方法,但没有找到这个方法
    • 也找不到。你找到版本了吗?
    猜你喜欢
    • 2019-01-08
    • 2013-07-17
    • 1970-01-01
    • 1970-01-01
    • 2014-01-30
    • 1970-01-01
    • 2016-03-30
    • 2019-08-05
    相关资源
    最近更新 更多