I have a JSON file ( myjsonfile.json
) which stores the folder structure along with file contents as a JSON. It is as follows:
{
"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"]
}]
}
]
}
What I want to do is access the content
of either of the two text files ( info1.txt
or data1.txt
) dynamically and store them as a List of Strings. By dynamically I mean that the filename ie, the key ( info1.txt
or data1.txt
) will be provided by the user.
I was able to parse and get the value in a static way by using org.json
library like this:
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...
However, I can't figure out how to make this dynamic and store the file contents as a List of Strings based on the user input of the filename.
Can someone please help me out?
EDIT: Clarified the question. myfilepath
here refers to the file path of the JSON file ( myjsonfile.json
).
You need to loop through each object and see if name
has the file you are looking for. I would recommend you use a more verbose JSON processing library such as Jackson or Gson to make things easier. However, given your current implementation, you want to do something along the lines of:
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;
}
Implement your own 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();
}
}
Simple usage:
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));
}
}
}
prints:
info1.txt contents -> [abcd, efgh, ijk]
data1.txt contents -> [abcd, xyz]
data2.txt contents -> []
Much easier to use Gson
library and class model of your JSON
payload. Let's create a class:
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 +
'}';
}
}
Which we can use as below:
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));
}
}
}
Above code prints:
info1.txt contents -> [abcd, efgh, ijk]
data1.txt contents -> [abcd, xyz]
data2.txt contents -> []
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.