简体   繁体   中英

How to parse complex nested jsonarray tree in java

I have a JSON array like this:

[{
  "name": "com",
  "children": [
    {
      "name": "project",
      "children": [
        {
          "name": "server"
        },
        {
          "name": "client",
          "children": [
            {
              "name": "util"
            }
          ]
        }
      ]
    }
  ]
}]

And I need all the names from all the JSON objects. Is there any way to get this done in java?

I want a recursive function.

My expected result is like :

[
    {name:"com"},
    {"name":"project"},
    {"name":"server"},
    {"name":"client"},
    {"name":"util"}]

Wrote a little program to solve your problem.

A recursive Type Entity that has 2 attributes, "name" of type String and "children" of Type List . Since this is the structure of your peaceable JSON. The JSON then can be easily parsed using Jackson API in one line

List<Entity> clas = mapper.readValue(json,
                mapper.getTypeFactory().constructCollectionType(List.class, Entity.class));

After successfully creating the object, all we need to do is traverse it recursively through the hierarchy and in every step return the name attribute with some extra text that gives the result a valid JSON form. Code below.

Main.java

import java.io.IOException;
import java.util.List;

import org.codehaus.jackson.JsonParseException;
import org.codehaus.jackson.map.JsonMappingException;
import org.codehaus.jackson.map.ObjectMapper;

public class Main {
public static void main(String[] args) throws JsonParseException, JsonMappingException, IOException {

    String json = "[{\"name\":\"com\",\"children\":[{\"name\":\"project\",\"children\":[{\"name\":\"server\"},{\"name\":\"client\",\"children\":[{\"name\":\"util\"}]}]}]}]";

    ObjectMapper mapper = new ObjectMapper();
    List<Entity> clas = mapper.readValue(json,
            mapper.getTypeFactory().constructCollectionType(List.class, Entity.class));

    String names = getChildren(clas);
    String result = "[" + names.substring(0, names.length() - 1) + "]";

    System.out.println(result);
}

private static String getChildren(List<Entity> clas) {
    String names = "";
    for (Entity class1 : clas) {
        if (class1.getChildren() == null) {
            names += "{name : \"" + class1.getName() + "\"},";
            if (clas.indexOf(class1) == (clas.size() - 1)) {
                return names;
            }
            continue;
        }
        names += "{name : \"" + class1.getName() + "\"},";

        names += getChildren(class1.getChildren());
    }
    return names;
}
}

Entity.java

import java.util.List;
import org.codehaus.jackson.annotate.JsonIgnoreProperties;

@JsonIgnoreProperties(ignoreUnknown = true)
public  class Entity {

    String name;
    List<Entity> children;

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public List<Entity> getChildren() {
        return children;
    }

    public void setChildren(List<Entity> children) {
        this.children = children;
    }}

Just try to trigger the "[" and "]". Pass recursively a string that can add the cutted utile parts of the json to the new format. At end you can return this string to the original call.. when the recursive ends.

I was writting an example for you specific case but in C#, and it seems to eb easier without recursivity.

   public string GetNames(string originalJson)
        {
            string namesString = "[";
            bool newItem = false;

            for(int i = 0; i < originalJson.Length; i++ )
            {                
                if(newItem)
                {
                    if (originalJson[i] == ',')
                    {
                        newItem = false;
                        namesString += "}";
                    }

                    else
                        namesString += originalJson[i];

                }
                else if (originalJson[i] == '{')
                {
                    newItem = true;
                    namesString += "{";
                }


            }
            namesString = namesString.Substring(0, namesString.Length - 1);
            namesString += "]";
            return namesString;
        }

I am not sure if this is what you are looking for.

This is a simple recursive function to get all names properties from your json array:

public static Collection<String> getAllNames(JSONArray jsonArray, List<String> names) {
    for (int i = 0; i < jsonArray.length(); i++) {
        JSONObject object = jsonArray.getJSONObject(i);
        names.add(object.getString("name"));
        if (object.has("children")) {
            JSONArray children = object.getJSONArray("children");
            getAllNames(children, names);
        }
    }

    return names;
}

This will provide you a list of names that you can use to construct a new json array. A possible way is this:

 public static JSONArray getJsonArraysOfNames(List<String> names) {
    JSONArray jsonArray = new JSONArray();
    for (String name : names) {
        JSONObject object = new JSONObject();
        object.put("name", name);
        jsonArray.put(object);
    }

    return jsonArray;
}

UPDATE

If you prefer an all-in-one solution then you can go with this approach:

public static JSONArray getNames(JSONArray inputArray, JSONArray outputArray) {
    for (int i = 0; i < inputArray.length(); i++) {
        JSONObject inputObject = inputArray.getJSONObject(i);

        JSONObject outputObject = new JSONObject();
        outputObject.put("name", inputObject.getString("name"));
        outputArray.put(outputObject);

        if (inputObject.has("children")) {
            JSONArray children = inputObject.getJSONArray("children");
            getNames(children, outputArray);
        }
    }

    return outputArray;
}

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.

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