如何从 JSON 字符串中获取值的所有 JSON 路径的列表?
How do I get a list of all JSON paths to values from a JSON String?
我的目标是读取一个 JSON 文件并了解所有值的位置,这样当我遇到相同的 JSON 时,我可以轻松读取所有值。我正在寻找一种方法 return 包含每个数据值的所有路径的列表,格式为 Jayway JsonPath。
示例JSON:
{
"shopper": {
"Id": "4973860941232342",
"Context": {
"CollapseOrderItems": false,
"IsTest": false
}
},
"SelfIdentifiersData": {
"SelfIdentifierData": [
{
"SelfIdentifierType": {
"SelfIdentifierType": "111"
}
},
{
"SelfIdentifierType": {
"SelfIdentifierType": "2222"
}
}
]
}
}
理想情况下,我想将 JSON 作为字符串并执行如下操作:
String json = "{'shopper': {'Id': '4973860941232342', 'Context': {'CollapseOrderItems': false, 'IsTest': false } }, 'SelfIdentifiersData': {'SelfIdentifierData': [{'SelfIdentifierType': {'SelfIdentifierType': '111'} }, {'SelfIdentifierType': {'SelfIdentifierType': '2222'} } ] } }";
Configuration conf = Configuration.defaultConfiguration();
List<String> jsonPaths = JsonPath.using(conf).parse(json).read("$");
for (String path : jsonPaths) {
System.out.println(path);
}
此代码将打印此内容,这是 JSON:
中所有值的位置
$.shopper.Id
$.shopper.Context.CollapseOrderItems
$.shopper.Context.IsTest
$.SelfIdentifiersData[0].SelfIdentifierData.SelfIdentifierType.SelfIdentifierType
$.SelfIdentifiersData[1].SelfIdentifierData.SelfIdentifierType.SelfIdentifierType
然后理想情况下,我将能够获取该列表并解析相同的 JSON 对象以获取每个值。
//after list is created
Object document = Configuration.defaultConfiguration().jsonProvider().parse(json);
for (String path : jsonPaths) {
Object value = JsonPath.read(document, path);
//do something
}
我知道我可以获得一个表示 JSON 文件的地图,但我不确定是否提供同样的访问便利性来检索所有值。如果有一个简单的方法来处理 JSONPath,那就太好了,否则欢迎任何其他方法。
我想出了一个解决方案,分享一下以防其他人正在寻找同样的东西:
public class JsonParser {
private List<String> pathList;
private String json;
public JsonParser(String json) {
this.json = json;
this.pathList = new ArrayList<String>();
setJsonPaths(json);
}
public List<String> getPathList() {
return this.pathList;
}
private void setJsonPaths(String json) {
this.pathList = new ArrayList<String>();
JSONObject object = new JSONObject(json);
String jsonPath = "$";
if(json != JSONObject.NULL) {
readObject(object, jsonPath);
}
}
private void readObject(JSONObject object, String jsonPath) {
Iterator<String> keysItr = object.keys();
String parentPath = jsonPath;
while(keysItr.hasNext()) {
String key = keysItr.next();
Object value = object.get(key);
jsonPath = parentPath + "." + key;
if(value instanceof JSONArray) {
readArray((JSONArray) value, jsonPath);
}
else if(value instanceof JSONObject) {
readObject((JSONObject) value, jsonPath);
} else { // is a value
this.pathList.add(jsonPath);
}
}
}
private void readArray(JSONArray array, String jsonPath) {
String parentPath = jsonPath;
for(int i = 0; i < array.length(); i++) {
Object value = array.get(i);
jsonPath = parentPath + "[" + i + "]";
if(value instanceof JSONArray) {
readArray((JSONArray) value, jsonPath);
} else if(value instanceof JSONObject) {
readObject((JSONObject) value, jsonPath);
} else { // is a value
this.pathList.add(jsonPath);
}
}
}
}
参考这个实用程序:https://github.com/wnameless/json-flattener
完美回答您的要求。为复杂 json 字符串提供 Flattened map 和 Flattened strings。
我不是本文的作者,但已成功将其用于我的用例。
我的目标是读取一个 JSON 文件并了解所有值的位置,这样当我遇到相同的 JSON 时,我可以轻松读取所有值。我正在寻找一种方法 return 包含每个数据值的所有路径的列表,格式为 Jayway JsonPath。
示例JSON:
{
"shopper": {
"Id": "4973860941232342",
"Context": {
"CollapseOrderItems": false,
"IsTest": false
}
},
"SelfIdentifiersData": {
"SelfIdentifierData": [
{
"SelfIdentifierType": {
"SelfIdentifierType": "111"
}
},
{
"SelfIdentifierType": {
"SelfIdentifierType": "2222"
}
}
]
}
}
理想情况下,我想将 JSON 作为字符串并执行如下操作:
String json = "{'shopper': {'Id': '4973860941232342', 'Context': {'CollapseOrderItems': false, 'IsTest': false } }, 'SelfIdentifiersData': {'SelfIdentifierData': [{'SelfIdentifierType': {'SelfIdentifierType': '111'} }, {'SelfIdentifierType': {'SelfIdentifierType': '2222'} } ] } }";
Configuration conf = Configuration.defaultConfiguration();
List<String> jsonPaths = JsonPath.using(conf).parse(json).read("$");
for (String path : jsonPaths) {
System.out.println(path);
}
此代码将打印此内容,这是 JSON:
中所有值的位置$.shopper.Id
$.shopper.Context.CollapseOrderItems
$.shopper.Context.IsTest
$.SelfIdentifiersData[0].SelfIdentifierData.SelfIdentifierType.SelfIdentifierType
$.SelfIdentifiersData[1].SelfIdentifierData.SelfIdentifierType.SelfIdentifierType
然后理想情况下,我将能够获取该列表并解析相同的 JSON 对象以获取每个值。
//after list is created
Object document = Configuration.defaultConfiguration().jsonProvider().parse(json);
for (String path : jsonPaths) {
Object value = JsonPath.read(document, path);
//do something
}
我知道我可以获得一个表示 JSON 文件的地图,但我不确定是否提供同样的访问便利性来检索所有值。如果有一个简单的方法来处理 JSONPath,那就太好了,否则欢迎任何其他方法。
我想出了一个解决方案,分享一下以防其他人正在寻找同样的东西:
public class JsonParser {
private List<String> pathList;
private String json;
public JsonParser(String json) {
this.json = json;
this.pathList = new ArrayList<String>();
setJsonPaths(json);
}
public List<String> getPathList() {
return this.pathList;
}
private void setJsonPaths(String json) {
this.pathList = new ArrayList<String>();
JSONObject object = new JSONObject(json);
String jsonPath = "$";
if(json != JSONObject.NULL) {
readObject(object, jsonPath);
}
}
private void readObject(JSONObject object, String jsonPath) {
Iterator<String> keysItr = object.keys();
String parentPath = jsonPath;
while(keysItr.hasNext()) {
String key = keysItr.next();
Object value = object.get(key);
jsonPath = parentPath + "." + key;
if(value instanceof JSONArray) {
readArray((JSONArray) value, jsonPath);
}
else if(value instanceof JSONObject) {
readObject((JSONObject) value, jsonPath);
} else { // is a value
this.pathList.add(jsonPath);
}
}
}
private void readArray(JSONArray array, String jsonPath) {
String parentPath = jsonPath;
for(int i = 0; i < array.length(); i++) {
Object value = array.get(i);
jsonPath = parentPath + "[" + i + "]";
if(value instanceof JSONArray) {
readArray((JSONArray) value, jsonPath);
} else if(value instanceof JSONObject) {
readObject((JSONObject) value, jsonPath);
} else { // is a value
this.pathList.add(jsonPath);
}
}
}
}
参考这个实用程序:https://github.com/wnameless/json-flattener 完美回答您的要求。为复杂 json 字符串提供 Flattened map 和 Flattened strings。 我不是本文的作者,但已成功将其用于我的用例。