参数与Java类名匹配的Groovy模板引擎
我相信这很简单 我们使用Groovy模板引擎将XML文档格式化为人类可读的形式。代码扫描XML并为XML中的每个项目创建一个带有条目的映射,然后将其传递给Groovy模板引擎 当XML包含与类名匹配的属性时会出现问题- 类似这样的内容:参数与Java类名匹配的Groovy模板引擎,groovy,Groovy,我相信这很简单 我们使用Groovy模板引擎将XML文档格式化为人类可读的形式。代码扫描XML并为XML中的每个项目创建一个带有条目的映射,然后将其传递给Groovy模板引擎 当XML包含与类名匹配的属性时会出现问题- 类似这样的内容:某个日期。如果模板文件指定Date为$Date(例如),而不是实际的日期字符串,我们将得到类java.util.Date。我们尝试了$Date的变体,如${Date}和${Date.toString()}等,但没有成功 我们认为问题在于Groovy混淆了Date输
某个日期
。如果模板文件指定Date为$Date
(例如),而不是实际的日期字符串,我们将得到类java.util.Date
。我们尝试了$Date
的变体,如${Date}
和${Date.toString()}
等,但没有成功
我们认为问题在于Groovy混淆了Date输入变量和java.util.Date类,但我确信有某种语法可以使其正常工作。因为我们通过这个方法提供任意用户定义的XML,所以我们实际上无法控制XML中的属性名称之类的东西
这里有几行代码可以复制这个问题:
def map = [:]
map.putAt("Date", new Date()) // Fails
map.putAt("Date2", new Date()) // Works
def tf = new File("Test.template")
def gte = new GStringTemplateEngine()
def tpl = gte.createTemplate(tf).make(map.withDefault{null})
println tpl.toString()
“Test.template”文件包含:
Date is ${Date.toString()}.
Date is ${Date2.toString()}.
我们得到的结果是:
Date is class java.util.Date.
Date is Tue Jun 06 20:22:16 EDT 2017.
是的,groovy似乎在绑定名为
Date
那么,为什么不将所有xml属性作为一个绑定变量传递呢
def map = [:]
map.putAt("Date", new Date()) // Fails
map.putAt("Date2", new Date()) // Works
def gte = new groovy.text.GStringTemplateEngine()
def tpl = gte.createTemplate('''
Date :: ${ctx.Date.toString()}
Date2 :: ${ctx.Date2.toString()}
''').make( [ctx:map].withDefault{null})
println tpl.toString()
也可以通过这种访问器委托访问变量。“我的奇怪变量”
:
def map = [:]
map.putAt("Date", new Date()) // Fails
map.putAt("Date2", new Date()) // Works
def gte = new groovy.text.GStringTemplateEngine()
def tpl = gte.createTemplate('''
Date :: ${delegate.'Date'.toString()}
Date2 :: ${Date2.toString()}
''').make( map.withDefault{null})
println tpl.toString()
在这里回答我自己的问题,以防万一其他人也有类似的问题 我们发现Groovy“getVariable()”方法是一种适合我们的解决方案。getVariable()方法返回任何变量的值,并在模板引擎中公开。将上面示例中的模板更改为:
Date is ${getVariable("Date")}
为我们解决了这个问题 我相信模板引擎是区分大小写的,对吗?在将标记值放入地图之前,是否可以尝试将其大写?否则,将其设置为可以访问另一个对象的子对象。比如myThing.Date.toString。这将确保您拥有正确的日期。可能存在数百个现有模板的副本,因此您的建议需要更改它们,我们希望避免这种情况。您可以以旧样式和新样式传递变量。对于您提到的情况,请使用新样式访问器,或者对于所有新模板,请使用新访问器。因此,您可以同时支持这两种方法。顺便说一句,当您的变量在中被命名为关键字
,如果
。。。