简体   繁体   English

动态地从json字符串创建和读取树数据结构

[英]Create and read tree data structure from json string dynamically

I'm trying to develop a dynamic query builder for days. 我正在尝试开发动态查询构建器几天。 But I'm having a problem with building it. 但我在构建它时遇到了问题。

What I'm reviving is a json like this. 我正在复兴的是像这样的json。

{"category":"Case Law","query":{"AND":{"Year":{"having":"","exact":"","any":"","none":""},"AND":{"Report":{"having":"","exact":"","any":"","none":""},"Citation":{"having":"","exact":"","any":"","none":""}}}}}

Here is it in much readable way 这是以可读的方式

Array
(
    [category] => Case Law
    [query] => Array
        (
            [OR] => Array
                (
                    [Year] => Array
                        (
                            [having] => some
                            [exact] => values
                            [any] => might
                            [none] => have
                        )

                    [AND] => Array
                        (
                            [Report] => Array
                                (
                                    [having] => 
                                    [exact] => 
                                    [any] => 
                                    [none] => 
                                )

                            [Citation] => Array
                                (
                                    [having] => 
                                    [exact] => 
                                    [any] => 
                                    [none] => 
                                )

                        )

                )

        )

)
  • this json can change according to the user inputs(can have more depth or less). 这个json可以根据用户输入进行更改(可以有更多深度或更少)。
  • what I'm trying to do is create a search query for apache lucene...(for the moment lets assume that leaf values are just strings.) 我正在尝试做的是为apache lucene创建一个搜索查询...(目前我们假设叶子值只是字符串。)

It must be something like this(What I need) 一定是这样的(我需要什么)

(Year:another values OR (Report:some valeus AND Citation:some valeues)) (年份:另一个值OR(报告:一些valeus和引用:一些valeues))

I tried with Jettison library and used DefaultMutableTreeNode to create the tree structure . 我尝试使用Jettison库并使用DefaultMutableTreeNode来创建树结构。 But it didn't work as I expected.Then i tried whit recursive functions and it also didn't worked 但它没有像我预期的那样工作。然后我尝试了whit递归函数,它也没有用

I want to is it possible to create this kind of thing. 我想是否有可能创造这种东西。 If yes how to do. 如果是,该怎么做。

Your attempt is highly appreciated! 非常感谢您的尝试! Thanks in advance. 提前致谢。

Ok Now the requirement is clear and here is the solution 好现在要求很明确,这是解决方案

define your operations 定义您的运营

enum MyOperator {

  AND,
  OR

}

Write a class to hold you atomic operaton 写一个类来保持原子操作

class AtomicOperation {

   Object lhs;
   Object rhs;
   MyOperator operator;

}

Now if You want something like (Year:another values OR (Report:some valeus AND Citation:some valeues)) 现在,如果你想要的东西(年份:另一个价值观或(报告:一些valeus和引用:一些valeues))

your JSON should look like : 你的JSON应该是这样的:

String jsonString = {{Year:['2001','2002']} OR {{Report:['Report1']} AND {Citation:['Citation1']}}}

So First Cast this JSON to AtominOperation class using the code 所以首先使用代码将此JSON转换为AtominOperation类

ConvertJsonToObject.getFromJSON(jsonString,AtominOperation.class);

GSON will cast it to a Simple AtominOperation Object with operation "OR"
and lhs,rhs as 2 LinkedHashMaps (Default behaviour of GSON)

Now use the below method to get the proper AtomicOperation Object from the
above AtomicOperation Object.

public static AtomicOperation deriveFromJSON(AtomicOperation operation) {

        if (operation.getLhs().getClass().equals(LinkedHashMap.class)) {
            AtomicOperation leftOperation = deriveFromJSON(ConvertJsonToObject
                    .getFromJSON(ConvertJsonToObject.toJSON(operation.getLhs()),
                            AtomicOperation.class));
            AtomicOperation rightOperation = deriveFromJSON(ConvertJsonToObject
                    .getFromJSON(ConvertJsonToObject.toJSON(operation.getRhs()),
                            AtomicOperation.class));
            return new AtomicOperation(leftOperation, operation.getOperator(),
                    rightOperation);
        }
        return operation;

    }

The Final AtomicOperation Object would be what u want. 最终的AtomicOperation对象将是您想要的。 :) :)

The JSON String for you query 您查询的JSON字符串

Ok. 好。 This is what i tried. 这是我试过的。

(Year:another values OR (Report:some valeus AND Citation:some valeues AND Field: another)) (年份:另一个值OR(报告:一些valeus和引用:一些valeues和Field:另一个))

should be something like : 应该是这样的:

String json = 
{"lhs":{"lhs":{"lhs":{"lhs":"Field","rhs":"Value","operator":"EQUAL_TO"},"rhs":{"lhs":"Citation","rhs":"Citation","operator":"EQUAL_TO"},"operator":"AND"},"rhs":{"lhs":"Report","rhs":"Report1","operator":"EQUAL_TO"},"operator":"AND"},"rhs":{"lhs":"Year","rhs":"2001","operator":"EQUAL_TO"},"operator":"OR"}

if The MYOperator enum is : 如果MYOperator枚举是:

public enum MyOperator {

    AND,
    OR,
    EQUAL_TO {
    @Override
    public String toString() {
        return ":";
    }
},
    IN

}

and AtomicOperation Is 和AtomicOperation是

public class AtomicOperation {


     Object lhs;
     Object rhs;
     MyOperator operator;

     AtomicOperation(Object lhs,MyOperator operator, Object rhs) {
         this.lhs = lhs;
         this.rhs = rhs;
         this.operator = operator;
     }

    public Object getLhs() {
        return lhs;
    }
    public void setLhs(Object lhs) {
        this.lhs = lhs;
    }
    public Object getRhs() {
        return rhs;
    }
    public void setRhs(Object rhs) {
        this.rhs = rhs;
    }
    public MyOperator getOperator() {
        return operator;
    }
    public void setOperator(MyOperator operator) {
        this.operator = operator;
    }

     @Override
public String toString() {
        return "(" + lhs.toString() + " " + operator.toString() + " " + rhs.toString() + ")"; 
}

}

Then You can Build the necessary AtomicOperation Object using the below code 然后,您可以使用以下代码构建必要的AtomicOperation对象

AtomicOperation _r = deriveFromJSON(ConvertJsonToObject.getFromJSON(json,AtomicOperation.class));

Below is the complete ConvertJsonToObject class 下面是完整的ConvertJsonToObject类

public class ConvertJsonToObject {

    private static Gson gson = new GsonBuilder().create();

    public static final <T> T getFromJSON(String json, Class<T> clazz) {
        return gson.fromJson(json, clazz);
    }

    public static final <T> String toJSON(T clazz) {
        return gson.toJson(clazz);
    }
}
Use Something like Google Gson

class ConvertJsonToObject {

    private static Gson gson = new GsonBuilder().create();

    public static final <T> T getFromJSON(String json, Class<T> clazz) {
        return gson.fromJson(json, clazz);
    }

}

String jsonString = "{"category":"Case Law","query":{"AND":{"Year the case was instituted":{"having":"","exact":"","any":"","none":""},"AND":{"Report":{"having":"","exact":"","any":"","none":""},"Citation":{"having":"","exact":"","any":"","none":""}}}}}
"

Now you can use ConvertJsonToObject.getFromJSON(jsonString,Map.class);

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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