如何在Java中解析复杂的嵌套jsonarray树

时间:2019-02-11 10:40:39

标签: java arrays json

我有一个像这样的JSON数组:

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

我需要所有JSON对象中的所有名称。有什么办法可以在Java中完成此操作?

我想要一个递归函数。

我的预期结果是:

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

3 个答案:

答案 0 :(得分:2)

编写一个小程序来解决您的问题。

具有两个属性的递归类型实体字符串类型的“名称” “子级” 类型为列表。因为这是您的JSON的结构。然后可以使用Jackson API轻松地在一行中解析JSON

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

成功创建对象后,我们要做的就是遍历层次结构遍历对象,并在每一步中返回name属性以及一些额外的文本,这些文本将为结果提供有效的JSON格式。下面的代码。

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;
    }}

答案 1 :(得分:1)

只需尝试触发“ [”和“]”即可。递归传递一个字符串,该字符串可以将json的cuted utile部分添加到新格式。最后,可以在递归结束时将此字符串返回到原始调用。

我正在为您的特定案例编写示例,但使用C#,并且似乎无需递归即可轻松实现。

   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;
        }

我不确定这是否是您想要的。

答案 2 :(得分:1)

这是一个简单的递归函数,可从您的json数组中获取所有names属性:

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;
}

这将为您提供名称列表,可用于构造新的json数组。 一种可能的方式是这样:

 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;
}

更新

如果您希望使用 all-in-one 解决方案,则可以采用以下方法:

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;
}