简体   繁体   English

列出EL表达式中的自由变量

[英]List free variables in an EL expression

I have an application which contains some EL evaluation used for programmatic configuration. 我有一个包含用于程序配置的EL评估的应用程序。 Given an EL expression I want to get what free variables it contains without actually evaluating it. 给定一个EL表达式,我想获取它包含的自由变量,而无需实际评估它。 The intention is to provide a UI where end users can bind values to free variables before pressing an "evaluate" button. 目的是提供一个UI,最终用户可以在按下“评估”按钮之前将值绑定到自由变量。

Unfortunately javax.el.ValueExpression does not provide this functionality, so I may need to use vendor-specific API. 不幸的是javax.el.ValueExpression不提供此功能,因此我可能需要使用特定于供应商的API。 It is quite early in the development, so I have not yet fixed my choice of implementation. 这是开发的早期阶段,因此我尚未确定实现的选择。 I have thought of MVEL, JUEL and SpEL, but of course whatever I chose should have the functionality I described above. 我曾经考虑过MVEL,JUEL和SpEL,但是我选择的任何东西当然都应该具有上面描述的功能。

How about this... 这个怎么样...

    SpelExpression parseExpression = (SpelExpression) new SpelExpressionParser().parseExpression(expressionString);
    SpelNode node = parseExpression.getAST();
    List<String> vars = getVars(node);

...


private List<String> getVars(SpelNode node) {
    List<String> vars = new ArrayList<String>();
    for (int i = 0; i < node.getChildCount(); i++) {
        SpelNode child = node.getChild(i);
        if (child.getChildCount() > 0) {
            vars.addAll(getVars(child));
        }
        else {
            if (child instanceof VariableReference) {
                vars.add(child.toStringAST());
            }
        }
    }
    return vars;
}

MVEL's ParserContext can tell you all about the variables organized by locals and inputs. MVEL的ParserContext可以告诉您有关本地和输入组织的变量的所有信息。

ParserContext ctx = ParserContext.create();
MVEL.analysisCompile("a = 0; b = 0;", ctx);

HashMap<String, Class> vars = ctx.getVariables();

assert vars.containsKey("a") && Number.class.isAssignableFrom(vars.get("a"));
assert vars.containsKey("b") && Number.class.isAssignableFrom(vars.get("b"));

Gary's answer is good but it didn't work for me when the expression contained a single variable, eg "#var" (one node with no children). Gary的答案很好,但是当表达式包含单个变量(例如“ #var”(一个没有子节点的节点))时,它对我不起作用。 A small change: 一个小变化:

private Set<String> getVars(SpelNode node) {
    Set<String> vars = new HashSet<String>();
    if (node == null) {
        return vars;
    }

    if (node instanceof VariableReference) {
        // Remove the "#" to get the actual variable name
        vars.add(StringUtils.remove(node.toStringAST(), "#"));
    }

    for (int i = 0; i < node.getChildCount(); i++) {
        SpelNode child = node.getChild(i);
        vars.addAll(getVars(child));
    }

    return vars;
}

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

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