web-dev-qa-db-ja.com

Jackson JSON:json-treeからノード名を取得

Jacksonを使用してJSONツリーからノード名を受け取るにはどうすればよいですか? JSONファイルは次のようになります。

{  
    node1:"value1",
    node2:"value2",
    node3:{  
        node3.1:"value3.1",
        node3.2:"value3.2"
    }
}

私が持っています

JsonNode rootNode = mapper.readTree(fileReader);

のようなものが必要です

for (JsonNode node : rootNode){
    if (node.getName().equals("foo"){
        //bar
  }
}

ありがとう。

48
Oskar Alfons

この回答は、2 +(以前は1.8用に書かれた)より前のJacksonバージョンに適用されます。 Jacksonの新しいバージョンで動作するバージョンについては、 @ SupunSameeraの答え を参照してください。


「ノード名」のJSON用語は「キー」です。 JsonNode#iterator() にはキーが含まれていないため、 differently を繰り返す必要があります。

_for (Map.Entry<String, JsonNode> elt : rootNode.fields())
{
    if ("foo".equals(elt.getKey()))
    {
        // bar
    }
}
_

キーを表示する必要があるonlyの場合、 JsonNode#fieldNames() を使用して、物事を少し簡略化できます。

_for (String key : rootNode.fieldNames())
{
    if ("foo".equals(key))
    {
        // bar
    }
}
_

また、キー_"foo"_を持つノードを検索する場合は、 直接アクセス を使用できます。これにより、ループを使用するよりも優れたパフォーマンス(一定時間のルックアップ)とよりクリーンでクリアなコードが生成されます。

_JsonNode foo = rootNode.get("foo");
if (foo != null)
{
    // frob that widget
}
_
62
Matt Ball

Jackson 2+(com.fasterxml.jackson)、メソッドは少し異なります:

Iterator<Entry<String, JsonNode>> nodes = rootNode.get("foo").fields();

while (nodes.hasNext()) {
  Map.Entry<String, JsonNode> entry = (Map.Entry<String, JsonNode>) nodes.next();

  logger.info("key --> " + entry.getKey() + " value-->" + entry.getValue());
}
65
Supun Sameera

fields()とfieldNames()の両方が機能していませんでした。そして、キーを反復処理する方法を見つけるために、かなりの時間を費やさなければなりませんでした。それを行うには2つの方法があります。

1つは、マップに変換することです(より多くのスペースを占有します)。

ObjectMapper mapper = new ObjectMapper();
Map<String, Object> result = mapper.convertValue(jsonNode, Map.class);
for (String key : result.keySet())
{
    if(key.equals(foo))
    {
        //code here
    }
}

もう1つは、Stringイテレーターを使用することです。

Iterator<String> it = jsonNode.getFieldNames();
while (it.hasNext())
{
    String key = it.next();
    if (key.equals(foo))
    {
         //code here
    }
}
11
Anna Shekhawat

ここでの明確化:

これは機能しますが:

 JsonNode rootNode = objectMapper.readTree(file);
 Iterator<Map.Entry<String, JsonNode>> fields = rootNode.fields();
 while (fields.hasNext()) {
    Map.Entry<String, JsonNode> entry = fields.next();
    log.info(entry.getKey() + ":" + entry.getValue())
 }

これはしません:

JsonNode rootNode = objectMapper.readTree(file);

while (rootNode.fields().hasNext()) {
    Map.Entry<String, JsonNode> entry = rootNode.fields().next();
    log.info(entry.getKey() + ":" + entry.getValue())
}

したがって、Iteratorを変数として宣言し、それを使用するよう注意してください。

fasterxmlではなく、codehausライブラリを使用してください。

7
ChrisGeo
JsonNode root = mapper.readTree(json);
root.at("/some-node").fields().forEachRemaining(e -> {
                              System.out.println(e.getKey()+"---"+ e.getValue());

        });

1行でJackson 2+

0
nash