将表达式的值作为groovy中的表达式进行求值

时间:2016-04-23 00:30:22

标签: groovy

以下是我正在努力工作的代码

    def expr = ''
    List params = []
    params << 'filter-name'
    params << 'servlet-name'
    params << 'url-pattern'

    params.each{expr = expr+ "it.'${it}'.text().trim()#"}
    expr = expr.substring(0, expr.length()-1)

    consNodes.each{
        println "data is:$"{expr}"
        println "actual : ${it.'filter-name'.text().trim()}#${it.'servlet-name'.text().trim()}#${it.'url-pattern'.text().trim()}"
}

在上面的结果就像

data is:it.'filter-name'.text().trim()#it.'servlet-name'.text().trim()#it.'url-pattern'.text().trim()
actual : presenceLogoutFilter##/adfAuthentication/*
data is:it.'filter-name'.text().trim()#it.'servlet-name'.text().trim()#it.'url-pattern'.text().trim()
actual : remoteApplication##/rr/*
data is:it.'filter-name'.text().trim()#it.'servlet-name'.text().trim()#it.'url-pattern'.text().trim()
actual : ServletADFContextFilter#GetHandler#
data is:it.'filter-name'.text().trim()#it.'servlet-name'.text().trim()#it.'url-pattern'.text().trim()
actual : ServletADFContextFilter##/PresenceServlet/*

因此,您可以看到我构建的表达式无法进一步评估。有关如何使其发挥作用的任何建议吗?

1 个答案:

答案 0 :(得分:3)

问题是您正在创建GString这样的代码:"it.'${it}'.text().trim()#",但是当您连接它时,它会将其转换为Stringexpr + "it.'${it}'.text().trim()#" 。将GString转换为String后,它不再评估表达式。但是,即使你解决它也无法解决你的问题,因为GString不会像你认为的那样进行评估。解释它的最好方法是举个例子:

import org.codehaus.groovy.runtime.GStringImpl

// What you're doing
def a = 'John'
def b = 'Hello, $a'
def c = "${a}"

assert b == 'Hello, $a'

// What the compiler is doing (ignoring the variable name changes)
def aa = 'John'
def bb = 'Hello, $a'
def cc = new GStringImpl([] as Object[], ['Hello, $a'] as String[])

assert cc == 'Hello, $a'

// What you want the compiler to do, but it will not.
def aaa = 'John'
def bbb = 'Hello, $a'
def ccc = new GStringImpl(['John'] as Object[], ['Hello, '] as String[])

assert ccc == 'Hello, John'

如果您真的想要,可以手动构建GString,但这将非常困难。而且你最终取决于一个不保证在Groovy版本之间保持向后兼容的类。

以下是您可以做的事情:

def params = []

params << 'filter-name'
params << 'servlet-name'
params << 'url-pattern'

def evaluators = params.collect { 
    { attr, node -> node[attr]?.text()?.trim() ?: '' }.curry(it)
}

consNodes.each { node ->
    println evaluators.collect { c -> c(node) }.join('#')    
}

输出如下:

presenceLogoutFilter##/adfAuthentication/*
remoteApplication##/rr/*
ServletADFContextFilter#GetHandler#
ServletADFContextFilter##/PresenceServlet/*

而不是单个大表达式,而不是闭包列表,每个闭包都负责评估节点属性。然后,您可以使用'#'加入结果。