繁体   English   中英

Java-动态访问嵌套的JSONArray值

[英]Java - Access Nested JSONArray values dynamically

我有一个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 -> []

GSON

使用Gson库和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 -> []

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM