alibaba / fastjson

FASTJSON 2.0.x has been released, faster and more secure, recommend you upgrade.
https://github.com/alibaba/fastjson2/wiki/fastjson_1_upgrade_cn
Apache License 2.0
25.72k stars 6.5k forks source link

jsonpath正确语法报illeal jsonpath syntax #2912

Open kevlxy opened 4 years ago

kevlxy commented 4 years ago

大佬您好,使用fastjson的时候发现一个问题, $.adList[?(@.catIds.length>0)].length这个语法不支持。

具体信息如下: fastjson版本: 1.2.60

jsonpath: $.adList[?(@.catIds.length>0)].length

运行时报错: com.alibaba.fastjson.JSONPathException: illeal jsonpath syntax. $.adList[?(@.catIds.length>0)].length

at com.alibaba.fastjson.JSONPath$JSONPathParser.readName(JSONPath.java:1584)
at com.alibaba.fastjson.JSONPath$JSONPathParser.readOp(JSONPath.java:1543)
at com.alibaba.fastjson.JSONPath$JSONPathParser.parseArrayAccessFilter(JSONPath.java:857)
at com.alibaba.fastjson.JSONPath$JSONPathParser.parseArrayAccess(JSONPath.java:786)
at com.alibaba.fastjson.JSONPath$JSONPathParser.readSegement(JSONPath.java:759)
at com.alibaba.fastjson.JSONPath$JSONPathParser.explain(JSONPath.java:1648)
at com.alibaba.fastjson.JSONPath.init(JSONPath.java:61)
at com.alibaba.fastjson.JSONPath.eval(JSONPath.java:71)
at com.alibaba.fastjson.JSONPath.eval(JSONPath.java:455)
hulog commented 4 years ago

目前api好像还不支持。顶多拿到catIdsvalue对象进行 有限 处理。这些处理,如下:

  1. 数值过滤(== != < > <= >= 等)
  2. 字符串过滤(=~ like等)

但你的catIds对应的数组对象,目前暂不能根据数组属性(length)进行过滤

解析流程流程如下:

Object parseArrayAccessFilter(boolean acceptBracket) {
    // omitted

    boolean self = false;
    if (ch == '@') {...}
    // 提取 path 中的 keyName
    String propertyName = readName();

    skipWhitespace();

    // ?(key) 型断言处理
    if (predicateFlag && ch == ')') {...}

    // [key] 型数组处理
    if (acceptBracket && ch == ']') {...}

    // 上面获取操作符左边的keyName
    // 当前 获取运算符
    Operator op = readOp();
    // 后面处理 运算符右边的数据
    // ?(key op ptn)
    // [key op ptn]

    if (op == Operator.BETWEEN || op == Operator.NOT_BETWEEN) {...}
    if (op == Operator.IN || op == Operator.NOT_IN) {...}
    if (ch == '\'' || ch == '"') {...}
    if (isDigitFirst(ch)) {...} else if (ch == '$') {...} else if (ch == '/') {...}

    // 处理 null/true/false 关键字
    if (ch == 'n') {} else if (ch == 't') {} else if (ch == 'f') {}
    throw new UnsupportedOperationException();
    // accept(')');

    // omitted
}
kevlxy commented 4 years ago

@hulog 可以支持一下这种情况吗?jmeter,com.jayway.jsonpath都是支持的