XmlSlurper made it simple

26 / Mar / 2010 by Amit Jain 1 comments

Hi! We had a myForm.html file (accessible only from the third party) where in we needed to update the form containing input/select/check boxes with the values we had in the request params and then render it. So we used xmlslurper for the same. Without much effort, it just worked great. Following is the code we wrote:

import org.ccil.cowan.tagsoup.*
import groovy.xml.*
import groovy.util.XmlSlurper
import javax.xml.parsers.SAXParser

public String parseAndUpdateHtml(Map params, String htmlContent) {
    htmlContent = htmlContent.replaceAll('selected="selected"', "")  //to remove already selected values in select box
    htmlContent = htmlContent.replaceAll('checked="checked"', "")  //to remove already selected values in check box

    @Grab(group = 'org.ccil.cowan.tagsoup', module = 'tagsoup', version = '1.2')
// Define our TagSoup backed parser
    def slurper = new XmlSlurper()
// Parse our html
    def html = slurper.parseText(htmlContent)

    params.each {id, value ->
      def htmlBody = html.body."**"
      def input = htmlBody.find { it.@id == id }   //name and id for all text boxes and select boxes were kept same
      if (input) {
        if (id.startsWith("txt")) {   // text box names had a prefix 'txt'
          input.@value = value
        } else if (id.startsWith("cmb")) {     // select box names had a prefix 'cmb'
          def option = input.option.list().find {it == value}
          if (option)
            option.@selected = "selected"

    params.each {name, value ->
      if (name.startsWith("cb") && value) {     // check box names had a prefix 'cb'
          def chkBoxvalues = [value].flatten()
          chkBoxvalues.each {chkBoxValue ->
          def htmlBody = html.body."**"
          def input = htmlBody.find { it.@type == "checkbox" && it.@name == name && it.@value == chkBoxValue }
          if (input) {
            input.@checked = "checked"

// Write it out (into a StringWriter for now)
    def w = new StringWriter()
    w << new StreamingMarkupBuilder().bind {
      // Required to avoid the html: namespace on every node
      mkp.declareNamespace '': 'http://www.w3.org/1999/xhtml'
      mkp.yield html
// XmlUtil.serialize neatens up our resultant xml -- but adds an xml declaration :-(
    return new XmlUtil().serialize(w.toString())

Thanks to tim_yates and others who helped me with this.

Hope this helped!

~~Amit Jain~~
IntelliGrape Software


comments (1 “XmlSlurper made it simple”)

  1. Donald

    You don’t actually declare a TagSoup backed parser in your example. To do that you would need to declare “def slurper = new XmlSlurper(new Parser())” instead of “def slurper = new XmlSlurper()”


Leave a comment -