我希望JsonPath始终将其解析的数据作为字符串返回。但是,JsonPath的read()
方法的返回类型取决于要解析的数据的类型,因为JsonPath总是猜测数据类型是什么并返回该类型的结果。
问题是我无法知道将返回什么类型的数据,因为我只能访问我需要提供给read()
函数的一组路径。这意味着我必须将返回的JsonPath数据存储在一个Object数组中,并使用包含instanceof
关键字的if / else-if语句的非常难看的集合来确定数据是什么(然后将其转换为适当的类型)。
有没有人知道强制JsonPath返回字符串的方法?或者另一个人可以想到更好的工作吗?
这就是我现在正在做的事情(用Java):
ArrayList<Object> realData = JsonPath.read(dataDumpFile, current.getPath());
我想做什么:
ArrayList<String> realData = JsonPath.read(dataDumpFile, current.getPath());
在docs我发现了这个:
在java中使用JsonPath时,了解结果中的预期类型非常重要。 JsonPath将自动尝试将结果转换为调用者期望的类型。
//Will throw an java.lang.ClassCastException List<String> list = JsonPath.parse(json).read("$.store.book[0].author") //Works fine String author = JsonPath.parse(json).read("$.store.book[0].author")
“调用者所期望的类型”是什么意思?
答案 0 :(得分:5)
在JsonPath的典型用例中,库假定为we know what to expect from a path:
路径明确?路径是:
$..book[0]
第一本书。$..book[?(@.isbn)]
;返回类型可以是列表。结果应该是什么特定类型?例如,您可以期望返回类型Date
或List<Date>
而不是Object
或List<Object>
。
在您的情况下,上述所有内容都无关紧要,因为您事先不知道类型,只需要将结果作为JSON字符串。
JsonPath中的默认解析器太聪明了,会将所有内容转换为漂亮的LinkedHashMap对象;但是如果你使用JacksonJsonNodeJsonProvider,你会得到JsonNode个对象的结果,并且你只有一个toString()
来自JSON字符串结果。
更好的是,您可以使用JsonPath option ALWAYS_RETURN_LIST
,这意味着您无需担心路径是明确的还是无限期的(无论结果是单个对象还是列表) )。
// Example from https://github.com/jayway/JsonPath#path-examples
final String json = "{\"store\": {\"book\": [{\"category\": \"reference\",\"author\": \"Nigel Rees\",\"title\": \"Sayings of the Century\",\"price\": 8.95},{\"category\": \"fiction\",\"author\": \"Evelyn Waugh\",\"title\": \"Sword of Honour\",\"price\": 12.99},{\"category\": \"fiction\",\"author\": \"Herman Melville\",\"title\": \"Moby Dick\",\"isbn\": \"0-553-21311-3\",\"price\": 8.99},{\"category\": \"fiction\",\"author\": \"J. R. R. Tolkien\",\"title\": \"The Lord of the Rings\",\"isbn\": \"0-395-19395-8\",\"price\": 22.99}],\"bicycle\": {\"color\": \"red\",\"price\": 19.95}},\"expensive\": 10}";
Configuration conf = Configuration.builder().jsonProvider(new JacksonJsonNodeJsonProvider())
.options(Option.ALWAYS_RETURN_LIST, Option.SUPPRESS_EXCEPTIONS).build();
ArrayNode node = JsonPath.using(conf).parse(json).read("$.store.book[*]"); // indefinite
for (Object o : node) {
System.out.println(o.toString());
}
// {"category":"reference","author":"Nigel Rees","title":"Sayings of the Century","price":8.95}
// {"category":"fiction","author":"Evelyn Waugh","title":"Sword of Honour","price":12.99}
// {"category":"fiction","author":"Herman Melville","title":"Moby Dick","isbn":"0-553-21311-3","price":8.99}
// {"category":"fiction","author":"J. R. R. Tolkien","title":"The Lord of the Rings","isbn":"0-395-19395-8","price":22.99}
node = JsonPath.using(conf).parse(json).read("$.store.book[0].author"); // definite
for (Object o : node) {
System.out.println(o.toString());
}
// "Nigel Rees"
答案 1 :(得分:0)
假设这是你的JSON:
{
"store": {
"book": [
{
"category": "reference",
"author": "Nigel Rees",
"title": "Sayings of the Century",
"price": 8.95
},
{
"category": "fiction",
"author": "Evelyn Waugh",
"title": "Sword of Honour",
"price": 12.99
},
{
"category": "fiction",
"author": "Herman Melville",
"title": "Moby Dick",
"isbn": "0-553-21311-3",
"price": 8.99
},
{
"category": "fiction",
"author": "J. R. R. Tolkien",
"title": "The Lord of the Rings",
"isbn": "0-395-19395-8",
"price": 22.99
}
],
"bicycle": {
"color": "red",
"price": 19.95
}
},
"expensive": 10
}
不是解析整个JSON,而是可以查询并获取那些字符串值(作为路径),然后您可以轻松地遍历它们并获得您想要的内容:
Configuration conf = Configuration.builder()
.options(Option.AS_PATH_LIST).build();
List<String> authorPathList = using(conf).parse(json).read("$..author");
这将返回作者路径列表:
["$['store']['book'][0]['author']",
"$['store']['book'][1]['author']",
"$['store']['book'][2]['author']",
"$['store']['book'][3]['author']"]
现在你可以遍历它们并获得你的价值:
for (string authorPath : authorPathList) {
String author = JsonPath.parse(json).read(authorPath);
}