解析java

时间:2018-04-13 06:24:59

标签: java json

我无法找到如何遍历JSON树(嵌套结构)并决定元素的键,接下来会发生什么,从节点到节点遍历。像这样(伪代码):

int  traverse(node) {
  if (node.key == ADD) {
    int res = 0; 
    for (child:node.children)  
     res = res + traverse(child);
  }
  if (node.key == "ADD") {
  int res = 0; 
  for (child:node.children) 
    res = res + traverse(children);
  }
  if (node.key == "MULT") {
    int res = 0; 
    for (child:node.children) 
      res = res * traverse(children);
  }

  if (node.key == "INT")  
    return node.value;
}

要解析的json-string可能是这样的:

 {"ADD":[{"INT":"1"},{"INT":"3"},{"INT":"4"}]}

或者这个:

 {"ADD":[{"INT":"1"},{"INT":"3"},{"ADD":[{"INT":"5"},{"INT":"6"}]},      
 {"INT":"4"}]}

我如何使用JSON-Object或JSON-Arrays和 在对象内部访问键和值变量以递归遍历此树?

EDITED: 在所有评论之后,我尝试将其作为第一个运行示例 (看起来对我来说仍然有些不安,但它确实有效):

public static int evaluate(javax.json.JsonObject node) {

  Set<?> keySet = node.keySet(); 
  Iterator<?> i = keySet.iterator(); 
  if (i.hasNext()) { 
    String key = i.next().toString();
        System.out.println("key: " + key);      
    if (key.equals("ADD"))  {
      JsonArray ja = node.getJsonArray("ADD");
      int  res = 0;
      for (JsonValue jvx: ja) {
    if (jvx.getValueType().toString().equals("OBJECT"))  {
      res = res + evaluate((JsonObject)jvx);        
            }  else{
      System.err.println("jvx should not be a " + jvx.getValueType().toString() + " here");
        }
      }
      return res;
    }
    if (key.equals("MULT"))  {
      JsonArray ja = node.getJsonArray("MULT");
      int  res = 1;
      for (JsonValue jvx: ja) {
    if (jvx.getValueType().toString().equals("OBJECT"))  {
      res = res * evaluate((JsonObject)jvx);        
            }  else{
      System.err.println("jvx should not be a " + jvx.getValueType().toString() + " here");
        }
      }
      return res;
    }
    if (key.equals("INT")) {
      String intStr = node.getString("INT");
      System.out.println ("found int = " + intStr);
      return Integer.parseInt(intStr);

        }
      }
      return 0; 
}


public static  void readJSON() {
  String jsonText =  "{\"ADD\":[{\"INT\":\"1\"},{\"INT\":\"3\"},{\"ADD\":[{\"INT\":\"5\"},{\"INT\":\"6\"}]},{\"INT\":\"4\"}]}";
      JsonReader reader = Json.createReader(new StringReader(jsonText));
      JsonObject obj = reader.readObject();
      reader.close();
      int res = evaluate(obj);
  System.out.println("res: " + res); 
}      

1 个答案:

答案 0 :(得分:1)

您的评估伪代码是正常的(只需在乘法时注意初始值!)。要使其适应javax.json层次结构,您应该像这样编写评估方法:

int evaluate(javax.json.JsonObject node)

  • 通过ADD获取所允许的密钥(MULTINTnode.getJsonObject(key)等):如果它返回null,请检查下一个允许的密钥,并在你找到的第一个停止。
  • 在每次操作时,必须编写适当的逻辑:
    1. 如果密钥是常量值(INT),请立即返回其值。
    2. 如果密钥是操作,请检查值的类型(通过node.getValueType()):如果是单个值,则按原样返回。如果它是一个数组,则遍历其元素并为每个元素调用evaluate,并使用返回值(添加,乘法等)执行正确的操作。最后,返回计算结果。

第一次编辑后

你的第一个真正的方法看起来不错;我建议您进行一些改进,以使代码更具可读性:

  1. 使用增强功能
  2. switch替换if-else通道。
  3. 通过调用私有方法替换每个案例。

    int result;
    Set<String> keySet = node.keySet(); 
    for (String key : keySet)
    {
        switch (key)
        {
            case "ADD":
                result=evaluateAdd(node.getJsonArray("ADD"));
                break;
            case "MULT":
                result=evaluateMult(node.getJsonArray("ADD"));
                break;
            case "INT":
                result=node.getInt("INT");
                break;
             ...
        }
    }