简体   繁体   中英

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

using the grails ws-lite 0.7.2.0, you specify an XML message to be sent via soap thusly:

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

What I need to do, is replace one of the static elements, eg "GetMothersDay" with a dynamic variable, eg:

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)
     }
  }
}

Obviously the above code wont work, but hopefully it illustrates what I am trying to do.

As a bonus question, what is that stuff which is in the outer {}? Are they function definitions? eg what is "year(2011)", it cant be a function definition and a function call at the same time?

The actual XML messages i need to replace bits of are much longer and more complicated - but essentially the same for each call.

Any help greatly appreciated - if there is no way to do this, I am faced with many hundreds of lines of duplicate code.

Instead of $action , use "$action" , or "${action}" if the expression is more complex than one variable and has spaces or other problematic characters.

These are method calls, and that's typically how Groovy DSLs/builders work. They're obviously not valid methods, but a method-missing / property-missing handler is active and as long as the methods you're calling are valid for the DSL, they'll be converted into what you're trying to build. Typically the name and/or the args of the method calls are used as data and to determine if the calls are valid.

For the regular groovy.xml.MarkupBuilder (eg in this example ), the methods that include a Map argument become elements with the name derived from the method name, and the Map items become attributes, eg

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

to

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

Methods calls with a String arg become elements with a String body, eg

country('Isle of Man')

becomes

<country>Isle of Man</country>

You can see in the source of SOAPMessageBuilder.groovy that the closure's delegate is set to the builder so it can process the calls, and it uses a MarkupBuilder to generate the XML string.

Programming Groovy 2 has particularly good coverage of creating DSLs in Groovy.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM