java - JAVA中的动态Json解析并找到键和值对?
问题描述
请记住,JSON 结构事先是未知的,即它是完全任意的,我们只知道它是 JSON 格式。
例如,以下 JSON
{
"id": 1,
"name": "Foo",
"price": 123,
"tags": [
{
"Bar":"23",
"Eek":"24"
}
]
}
我们可以这样做来遍历树并跟踪我们想要找出点符号属性名称的深度。
我们如何在编译时获取数据唯一的键和在运行时获取值。
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.node.ArrayNode;
import com.fasterxml.jackson.databind.node.ObjectNode;
import com.fasterxml.jackson.databind.node.ValueNode;
import java.io.File;
import java.io.IOException;
import java.util.*;
public class Main {
public static void main(String[] args) {
File file=new File("src/data.json");
ObjectMapper mapper=new ObjectMapper();
try {
LinkedHashMap<String,String> map= new LinkedHashMap<String, String>();
JsonNode node =mapper.readTree(file);
getKeys("",node, map);
for (Map.Entry<String, String> entry : map.entrySet()) {
System.out.println("Key:"+entry.getKey() + ""+" "+" value:" + entry.getValue());
}
} catch (IOException e) {
e.printStackTrace();
}
}
public static void getKeys(String currentpath,JsonNode node,LinkedHashMap map){
if(node.isObject()){
ObjectNode objectNode=(ObjectNode) node;
Iterator<Map.Entry<String, JsonNode>> it=objectNode.fields();
String prefix=currentpath.isEmpty()?"":currentpath+".";
while (it.hasNext()){
SortedMap.Entry<String,JsonNode> iter=it.next();
getKeys(prefix+iter.getKey(),iter.getValue(),map);
}
}else if (node.isArray()){
ArrayNode arrayNode=(ArrayNode) node;
for(int i=0; i<arrayNode.size(); i++){
getKeys(currentpath+i,arrayNode.get(i),map);
}
}
else if(node.isValueNode()) {
ValueNode valueNode=(ValueNode) node;
map.put(currentpath,valueNode.asText());
}
}
}
在运行时只显示用户想要的值。
喜欢
输入:Address.street 输出:“23fn3 伦敦”
解决方案
处理您一无所知的 json 结构是不常见的。如果您不知道您在寻找什么值,那么这些数据将如何有用?
在您确实想要遍历整个树的特殊情况下,您将不得不使用递归。因为每个字段 ( field
) 都可以有一个简单的值 ( "field": 1
)、一个对象 ( "field": {"b": 1}
) 或一个数组 ( "field": [1, 2, 3]
)。
下面的代码展示了如何使用Jackson json 库来做到这一点
public static void main(String[] args) throws IOException {
File file = new File("data.json");
ObjectMapper mapper = new ObjectMapper();
JsonNode node = mapper.readTree(file);
processNode(node);
}
private static void processNode(JsonNode node) {
if(node.isArray()) {
// if the node is a list of items,
// go through all the items and process them individually
System.out.println("=== Array start ===");
for (final JsonNode objInArray : node) {
System.out.println("--- Array element start ---");
// process the item in the array
processNode(objInArray);
System.out.println("--- Array element end ---");
}
System.out.println("=== Array end ===");
} else if(node.isContainerNode()) {
// if the node is an object,
// go through all fields within the object
System.out.println("/// Object start ///");
Iterator<Map.Entry<String, JsonNode>> it = node.fields();
while (it.hasNext()) {
Map.Entry<String, JsonNode> field = it.next();
System.out.println("key: " + field.getKey());
//process every field in the array
processNode(field.getValue());
}
System.out.println("/// Object end ///");
} else {
// if node is a simple value (like string or int) so let's print it
System.out.println("value: " + node);
}
}
您提供的示例 json 提供以下输出:
=== Array start ===
--- Array element start ---
/// Object start ///
key: id
value: 1
key: name
value: "Leanne Graham"
key: username
value: "Bret"
key: email
value: "Sincere@april.biz"
key: address
/// Object start ///
key: street
value: " Light"
key: suite
value: "Apt. 556"
key: city
value: "Gwugh"
key: zipcode
value: "93874"
key: geo
/// Object start ///
key: lat
value: "-37.319"
key: lng
value: "81.146"
/// Object end ///
/// Object end ///
key: phone
value: "8031 x56442"
key: website
value: "hilded.org"
key: company
/// Object start ///
key: name
value: "Romra-Crona"
key: catchPhrase
value: " client-server neural-net"
key: bs
value: "harness markets"
/// Object end ///
/// Object end ///
--- Array element end ---
=== Array end ===
Process finished with exit code 0
推荐阅读
- javascript - 我无法在 Laravel 中使用 ajax 插入数据,我总是收到 500 内部服务器错误,我不知道为什么?
- python - 如何在 Python 中删除一式三份的字母
- python - Python:找出另一个应用程序是否打开文件的有效方法
- javascript - Highcharts 6时间线图
- excel - 我如何想出一个公式来解决以下问题:如果一个单元格为零,则将另一个单元格中的一个数字添加到总成本中?
- redmine - Redmine Rest API - 文件附件,上传令牌不完整
- python - 读取多个 JSON 文件并将数据转换为单个 CSV 文件
- ms-access - 用于多个查询的 MS Access 报告
- javascript - echarts:dataZoom 滑块不显示正确的数据预览
- java - 重新索引 Solr:java.lang.OutOfMemoryError:Java 堆空间 solr