【问题标题】:How to parse complex nested jsonarray tree in java如何在java中解析复杂的嵌套jsonarray树
【发布时间】:2019-02-11 10:40:38
【问题描述】:

我有一个这样的 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"}]

【问题讨论】:

  • 到目前为止你尝试过什么?为什么它不起作用?
  • JSONArray ja= new JSONArray(myarray); JSONObject jo= ja.getJSONObject(0); System.out.println(jo.getString("name"));实际上我正在尝试这样,所以它的解决方法类型我想要一个读取数组内嵌套数组的函数
  • 我的数据是动态的,所以我不知道有多少 json 对象被添加到 children 数组中,这就是为什么我想要一个通用函数来减少我的工作
  • 您删除其他问题有点快。看看stackoverflow.com/questions/4216745/… ...我会做什么:只需使用 String.substring() 来获取每行的前 X 个字符。 X 将是您知道时间戳需要的数字。然后尝试将该字符串解析为日期。如果效果好,如果效果不好,那你还有别的东西。
  • 但是请理解:那是非常基本的东西,你不应该来这里显示要求“这是我需要的”,以及 你自己解决问题的努力。请理解:我们帮助您解决问题我们不会为您解决问题。最后:小心:你已经有一些分数为负的问题,如果你继续这样,你可能会被禁止提问。所以,请:不要来这里指望人们向你展示超级基本的东西。以前在这里被问过很多次的东西。

标签: java arrays json


【解决方案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;
}

更新

如果您更喜欢一体化解决方案,那么您可以采用这种方法:

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

【讨论】:

    【解决方案2】:

    写了一个小程序来解决你的问题。

    一个递归类型 Entity,有 2 个属性,"name" 类型为 String"children" 列表类型。因为这是您的和平 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;
        }}
    

    【讨论】:

      【解决方案3】:

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

      我正在为您的特定情况编写一个示例,但使用的是 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;
              }
      

      我不确定这是否是您正在寻找的。

      【讨论】:

        猜你喜欢
        • 2021-09-23
        • 2017-05-01
        • 2017-09-22
        • 1970-01-01
        • 2021-03-17
        • 2021-01-25
        • 2017-09-02
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多