簡體   English   中英

列出EL表達式中的自由變量

[英]List free variables in an EL expression

我有一個包含用於程序配置的EL評估的應用程序。 給定一個EL表達式,我想獲取它包含的自由變量,而無需實際評估它。 目的是提供一個UI,最終用戶可以在按下“評估”按鈕之前將值綁定到自由變量。

不幸的是javax.el.ValueExpression不提供此功能,因此我可能需要使用特定於供應商的API。 這是開發的早期階段,因此我尚未確定實現的選擇。 我曾經考慮過MVEL,JUEL和SpEL,但是我選擇的任何東西當然都應該具有上面描述的功能。

這個怎么樣...

    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的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的答案很好,但是當表達式包含單個變量(例如“ #var”(一個沒有子節點的節點))時,它對我不起作用。 一個小變化:

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