2016-04-23 59 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) –