11

Jackson (バージョン 2.6+) を使用して、次のような醜いJSON を解析しています。

{ 
    "root" : { 
        "dynamic123" : "Some value"
    }
}

残念ながら、属性の名前はdynamic123実行時まで不明であり、時々異なる場合があります。私が達成しようとしているのは、JsonPointerを使用して値を取得することです"Some value"JsonPointerは、ここで説明されているXPathに似た構文を使用します。

// { "root" : { "dynamic123" : "Some value" } }
ObjectNode json = mapper.createObjectNode();
json.set("root", json.objectNode().put("dynamic123", "Some value"));

// Some basics
JsonNode document = json.at("");                      // Ok, the entire document
JsonNode missing = json.at("/missing");               // MissingNode (as expected)
JsonNode root = json.at("/root");                     // Ok -> { dynamic123 : "Some value" }

// Now, how do I get a hold of the value under "dynamic123" when I don't
// know the name of the node (since it is dynamic)
JsonNode obvious = json.at("/root/dynamic123");       // Duh, works. But the attribute name is unfortunately unknown so I can't use this
JsonNode rootWithSlash = json.at("/root/");           // MissingNode, does not work
JsonNode zeroIndex = json.at("/root[0]");             // MissingNode, not an array
JsonNode zeroIndexAfterSlash = json.at("/root/[0]");  // MissingNode, does not work

それで、今私の質問に。JsonPointer"Some value"を使用して値を取得する方法はありますか?

明らかに、値を取得する他の方法があります。考えられるアプローチの 1 つは、JsonNodeトラバーサル関数を使用することです。たとえば、次のようにします。

JsonNode root = json.at("/root");
JsonNode value = Optional.of(root)
        .filter(d -> d.fieldNames().hasNext()) // verify that there are any entries
        .map(d -> d.fieldNames().next())       // get hold of the dynamic name
        .map(name -> root.get(name))           // lookup of the value
        .orElse(MissingNode.getInstance());    // if it is missing

しかし、私はトラバーサルを避け、JsonPointerのみを使用しようとしています。

4

1 に答える 1

5

JsonPointer 仕様がワイルドカードをサポートしているとは思わない。それはかなり基本的です。代わりに、 JsonPathを Jackson マッピング プロバイダーで使用することを検討できます。次に例を示します。

public class JacksonJsonPath {
    public static void main(String[] args) {
        final ObjectMapper objectMapper = new ObjectMapper();
        final Configuration config = Configuration.builder()
                .jsonProvider(new JacksonJsonNodeJsonProvider())
                .mappingProvider(new JacksonMappingProvider())
                .build();

        // { "root" : { "dynamic123" : "Some value" } }
        ObjectNode json = objectMapper.createObjectNode();
        json.set("root", json.objectNode().put("dynamic123", "Some value"));

        final ArrayNode result = JsonPath
                .using(config)
                .parse(json).read("$.root.*", ArrayNode.class);
        System.out.println(result.get(0).asText());
    }
}

出力:

SLF4J: Failed to load class "org.slf4j.impl.StaticLoggerBinder".
SLF4J: Defaulting to no-operation (NOP) logger implementation
SLF4J: See http://www.slf4j.org/codes.html#StaticLoggerBinder for further details.
Some value
于 2016-03-11T22:51:13.020 に答える