web-dev-qa-db-ja.com

JavaでのJSONPathの基本的な使用

文字列としてのJSONと文字列としてのJSONPathがあります。 JSONパスでJSONをクエリし、結果のJSONを文字列として取得したいと思います。

私はそれを集めます Jaywayのjson-path標準ですオンラインAPI は、- Mavenから取得する実際のライブラリ とはあまり関係がありません。 GrepCodeのバージョン はほぼ一致します。

私はできるはずのようです:

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

問題は、readがJSONPathが実際に見つけたものに基づいて最も適切だと感じるものを何でも返すということです(例:List<Object>Stringdoubleなど)。したがって、特定のクエリに対してコードが例外をスローします。 JSONをクエリしてJSONを取得する何らかの方法があると想定するのはかなり合理的です。助言がありますか?

18
akroy

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"、 "repl": " N "、" cod ":" Y "、" is_oda ":" N "、" sort_code ":" GB "、" state_code ":" UP "}}]

これで、上記で取得したリスト(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 );
}

出力は次のようになります。

ピン:: 201001地区::ガジアバード

解析しようとしているJsonに応じて、リストをフェッチするか、単一の文字列/ロング値をフェッチするかを決定できます。

それがあなたの問題の解決に役立つことを願っています。

11
Ankur Choudhary

jayway JsonPath にあるJava JsonPath APIは、上記のすべての回答/コメントから少し変更されている可能性があります。ドキュメントも。上記のリンクをたどって 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);

これが誰にも役立つことを願っています。

7
francois

これらの長年の答えのいくつかがなぜ機能しないのか疑問に思う方は、 テストケース から多くを学ぶことができます。

2018年9月現在、Jackson JsonNodeの結果を取得する方法は次のとおりです。

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

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