grails/groovy 和 wslite - 如何使静态 XML 动态化?

grails/groovy and wslite - how to make the static XML dynamic?

使用 grails ws-lite 0.7.2.0,您指定要通过 soap 发送的 XML 消息:

  def response = send(SOAPAction: 'http://www.27seconds.com/Holidays/US/Dates/GetMothersDay') {
  body {
     GetMothersDay(xmlns: 'http://www.27seconds.com/Holidays/US/Dates/') {
        year(2011)
     }
  }
}

我需要做的是替换其中一个静态元素,例如"GetMothersDay" 带有动态变量,例如:

String action = "GetMothersDay"
def response = send(SOAPAction: 'http://www.27seconds.com/Holidays/US/Dates/GetMothersDay') {
  body {
     $action(xmlns: 'http://www.27seconds.com/Holidays/US/Dates/') {
        year(2011)
     }
  }
}

显然上面的代码不会工作,但希望它能说明我正在尝试做的事情。

作为奖励问题,外部 {} 中的那个东西是什么?它们是函数定义吗?例如什么是"year(2011)",不能同时是函数定义和函数调用吗?

我需要替换的实际 XML 消息更长更复杂 - 但每次调用基本相同。

非常感谢任何帮助 - 如果没有办法做到这一点,我将面临数百行重复代码。

如果表达式比一个变量更复杂并且包含空格或其他有问题的字符,请使用 "$action""${action}" 而不是 $action

这些是方法调用,这通常是 Groovy DSLs/builders 的工作方式。它们显然不是有效方法,但是缺少方法/属性 缺少处理程序处于活动状态,只要您调用的方法对 DSL 有效,它们就会被转换成您想要的试图建立。通常,名称 and/or 方法调用的参数用作数据并确定调用是否有效。

对于常规 groovy.xml.MarkupBuilder(例如 in this example),包含 Map 参数的方法成为具有从方法名称派生的名称的元素,并且 Map 项成为属性,例如

car(name:'P50', make:'Peel', year:1962) 

<car name='P50' make='Peel' year='1962'>

带有字符串参数的方法调用成为带有字符串主体的元素,例如

country('Isle of Man')

变成

<country>Isle of Man</country>

您可以在 the source of SOAPMessageBuilder.groovy 中看到闭包的 delegate 设置为构建器,因此它可以处理调用,并且它使用 MarkupBuilder 生成 XML 字符串。

Programming Groovy 2 对在 Groovy.

中创建 DSL 有特别好的介绍