以下是我正在努力工作的代码
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/*
因此,您可以看到我构建的表达式无法进一步评估。有关如何使其发挥作用的任何建议吗?
答案 0 :(得分:3)
问题是您正在创建GString
这样的代码:"it.'${it}'.text().trim()#"
,但是当您连接它时,它会将其转换为String
:expr + "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/*
而不是单个大表达式,而不是闭包列表,每个闭包都负责评估节点属性。然后,您可以使用'#'加入结果。