2016-04-23 47 views
0

下面的表达式作为表达式的值是我试图在上面的结果,以获得工作评估在常规

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/* 

所以,你可以看到我构建的表达式不能进一步评估。任何建议如何使其工作?

回答

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 S,但是这将是非常困难的。并且最终取决于不保证在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/* 

而不是一个单一的大表达你了倒闭的列表,每个负责评估一个节点属性。然后,你可以用'#'加入结果。

+0

这是怎么回事? –

+0

抱歉删除了错误的评论。是收集一个内置的封闭或只是任何名字? – Vik

+0

'collect(Closure)'是Groovy向Java的'Object'类添加的一种方法,(尽管在集合中使用它更常见)。它迭代一个集合,对每个项目执行闭包。然后,每个迭代的输出被收集并作为列表返回。请参阅http://docs.groovy-lang.org/latest/html/groovy-jdk/java/lang/Object.html#collect(groovy.lang.Closure) –