Java - 动态访问嵌套的 JSONArray 值



>我有一个JSON文件(myjsonfile.json),它将文件夹结构和文件内容存储为JSON。具体如下:

{
"name":"folder1",
"type":"directory",
"children":[
{"name":"info",
"type":"directory",
"children": [
{
"name":"info1.txt",
"type":"file",
"content": ["abcd", "efgh", "ijk"]
}]
},
{"name":"data",
"type":"directory",
"children": [{
"name":"data1.txt",
"type":"file",
"content": ["abcd", "xyz"]
}]
}
]
}

我想做的是动态访问两个文本文件(info1.txtdata1.txt)中的任何一个的content,并将它们存储为字符串列表。动态我的意思是文件名,即密钥(info1.txtdata1.txt)将由用户提供。

我能够使用这样的库以静态方式解析和获取值org.json

File file = new File(myfilepath/myjsonfile.json);
String jsonContent = null;
try {
content = FileUtils.readFileToString(file, "utf-8");
} catch (IOException e) {
e.printStackTrace();
}
// Convert JSON string to JSONObject
JSONObject jsonObj = new JSONObject(jsonContent);
JSONArray children =  jsonObj.getJSONArray("children");
System.out.println(children.toString());
JSONObject  child0 = children.getJSONObject(0);
System.out.println(child0.toString());
// and so on...

但是,我不知道如何使其动态并根据文件名的用户输入将文件内容存储为字符串列表。

有人可以帮我吗?

编辑:澄清了这个问题。myfilepath这里指的是 JSON 文件的文件路径 (myjsonfile.json)。

您需要遍历每个对象,看看name是否有您要查找的文件。 我建议您使用更详细的 JSON 处理库,例如 Jackson 或 Gson,以使事情变得更容易。 但是,鉴于您当前的实现,您希望执行以下操作:

if(jsonObj.has("children")) {
JSONArray mainChild = jsonObj.getJSONArray("children");
for(int i=0; i < mainChild.length(); i++) {
if(((JSONObject)mainChild.get(i)).has("children")) {
JSONArray child = ((JSONObject)mainChild.get(i)).getJSONArray("children");
for(int j=0; j < child.length(); j++) {
JSONObject obj = child.getJSONObject(j);
if(obj.has("name") 
&& fileNameToLookFor.equals(obj.getString("name"))) {
if(obj.has("content")) {
return obj.getJSONArray("content");
}
return null;
}
}
}
}
return null;
}

实现你自己的tree-node-walker

class NodeWalker {
private final JSONObject object;
public NodeWalker(JSONObject object) {
this.object = object;
}
public List<String> findContentFor(String name) {
LinkedList<JSONObject> queue = new LinkedList<>();
queue.add(object);
while (queue.size() > 0) {
JSONObject next = queue.pop();
Object fileName = next.get("name");
final String contentName = "content";
if (fileName != null && fileName.equals(name) && next.has(contentName)) {
JSONArray content = next.getJSONArray(contentName);
if (content == null) {
return Collections.emptyList();
}
List<String> result = new ArrayList<>();
IntStream.range(0, content.length()).forEach(i -> result.add(content.getString(i)));
return result;
}
final String childrenName = "children";
if (next.has(childrenName)) {
JSONArray array = next.getJSONArray(childrenName);
IntStream.range(0, array.length()).forEach(i -> queue.add(array.getJSONObject(i)));
}
}
return Collections.emptyList();
}
}

简单用法:

import org.json.JSONArray;
import org.json.JSONObject;
import java.io.File;
import java.nio.file.Files;
import java.util.ArrayList;
import java.util.Collections;
import java.util.LinkedList;
import java.util.List;
import java.util.stream.IntStream;
public class ProfileApp {
public static void main(String[] args) throws Exception {
File jsonFile = new File("./resource/test.json").getAbsoluteFile();
List<String> strings = Files.readAllLines(jsonFile.toPath());
String json = String.join("", strings);
JSONObject jsonObj = new JSONObject(json);
NodeWalker nodeWalker = new NodeWalker(jsonObj);
String[] files = {"info1.txt", "data1.txt", "data2.txt"};
for (String file : files) {
System.out.println(file + " contents -> " + nodeWalker.findContentFor(file));
}
}
}

指纹:

info1.txt contents -> [abcd, efgh, ijk]
data1.txt contents -> [abcd, xyz]
data2.txt contents -> []

格森

JSON有效负载的库和类模型Gson使用起来要容易得多。让我们创建一个类:

class FileNode {
private String name;
private String type;
private List<FileNode> children;
private List<String> content;
public List<String> findContent(String name) {
LinkedList<FileNode> queue = new LinkedList<>();
queue.add(this);
while (queue.size() > 0) {
FileNode next = queue.pop();
if (next.name.equals(name)) {
return next.content;
}
if (next.children != null) {
queue.addAll(next.children);
}
}
return Collections.emptyList();
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getType() {
return type;
}
public void setType(String type) {
this.type = type;
}
public List<FileNode> getChildren() {
return children;
}
public void setChildren(List<FileNode> children) {
this.children = children;
}
public List<String> getContent() {
return content;
}
public void setContent(List<String> content) {
this.content = content;
}
@Override
public String toString() {
return "FileNode{" +
"name='" + name + ''' +
", type='" + type + ''' +
", children=" + children +
", content=" + content +
'}';
}
}

我们可以按如下方式使用:

import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
import java.io.File;
import java.io.FileReader;
import java.util.Collections;
import java.util.LinkedList;
import java.util.List;
public class GsonApp {
public static void main(String[] args) throws Exception {
File jsonFile = new File("./resource/test.json").getAbsoluteFile();
Gson gson = new GsonBuilder()
.setPrettyPrinting()
.create();
FileNode root = gson.fromJson(new FileReader(jsonFile), FileNode.class);
String[] files = {"info1.txt", "data1.txt", "data2.txt"};
for (String file : files) {
System.out.println(file + " contents -> " + root.findContent(file));
}
}
}

上面的代码打印:

info1.txt contents -> [abcd, efgh, ijk]
data1.txt contents -> [abcd, xyz]
data2.txt contents -> []

最新更新