评价表达式在常规表达中的价值 [英] evaluating value of an expression as expression in groovy
问题描述
这里是我想要工作的代码
Here is the code i am trying to get working
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()}"
}
就像
in the above result comes like
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/*
因此,您可以看到我构建的表达式无法进一步评估。任何建议如何使它工作?
So, as you can see that my constructed expression is not able to evaluate further. Any advise on how to make it work?
推荐答案
问题是你正在创建一个 GString
像这样:it。'$ {it}'.text()。trim()#
,但是然后转换它当你连接它时,你可以将它放到一个 String
中: expr +it。'$ {it}'.text()。trim()# code>。一旦将
GString
变成字符串
,它不再评估表达式。但即使你提到它不能解决你的问题,因为 GString
不像你认为的那样评估。解释它的最好方法是用一个例子:
The problem is that you're creating a GString
like this: "it.'${it}'.text().trim()#"
, but then you're converting it into a String
when you concatenate it: expr + "it.'${it}'.text().trim()#"
. Once you turn a GString
into a String
it no longer evaluates expressions. But even if you address that it won't solve your problem because GString
s do not evaluate like you think they do. The best way to explain it is with an example:
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发行版之间保持向后兼容的类。
If you really want to, you can build the GString
s manually, but that will be very difficult. And you'd end up depending on a class which is not guaranteed to remain backward-compatible between Groovy releases.
以下是您可以做的事情:
Here's what you can do instead:
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('#')
}
输出看起来像这:
The output looks like this:
presenceLogoutFilter##/adfAuthentication/*
remoteApplication##/rr/*
ServletADFContextFilter#GetHandler#
ServletADFContextFilter##/PresenceServlet/*
并列出一系列闭包,每个负责评估节点属性。然后,您可以将结果加入'#'。
Instead of a single large expression you and up with a list of closures, each responsible for evaluating a node attribute. Then, you can join the results with '#'s.
这篇关于评价表达式在常规表达中的价值的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!