sqlgroovymarkupbuilder

Groovy Sql resultSet rendering to XML via MarkupBuilder


I am trying to generate XML output in Groovy (4.0.18) from generic SQL requests where the query is provided at runtime.

So I have captured the SQL results in a List (of ResultSets) and I captured the column names in a separate List (of Strings) -

List cols = []

List rows = myConnection.rows(sqlStatement) { metadata ->
  cols = (1..metadata.columnCount).collect { metadata.getColumnLabel(it) }
}

outputXmlResults(cols, rows)

And since the sqlStatement is provided at runtime the table and column names are not known until execution (of course). But the Sql rows() method returns all the rows and has a signature that provides all the column names so I have all the data (verified in debugger)...

Now I just need to output it in XML and wanted to use Groovy's MarkupBuilder so I passed in the two Lists to my outputXmlResults() method but started simple with hardcoded/assumed column names -

def outputXmlResults(List columns, List resultSet) {

    def builder = new MarkupBuilder()

    builder.queryResults {

        resultSet.each { row ->

            rowResult {

                    customer_uuid(row.customer_uuid)
                    first_name(row.first_name)
                    last_name(row.last_name)
            }
        }
    }
}

Now when I do it as listed above then everything works smoothly and this is produced -

<queryResults>
  <rowResult>
    <customer_uuid>eb8dcfcc-6ad0-41ca-b5fa-0e46d4fb67d9</customer_uuid>
    <first_name>Jocelyn</first_name>
    <last_name>Eyton</last_name>
  </rowResult>
  <rowResult>
    <customer_uuid>3d46633b-f938-40fc-af64-abea31c46d4d</customer_uuid>
    <first_name>Ignace</first_name>
    <last_name>Studdard</last_name>
  </rowResult>
  <rowResult>
    <customer_uuid>2db045e4-984a-494e-b5ce-516822630a66</customer_uuid>
    <first_name>Bethanne</first_name>
    <last_name>Bengoechea</last_name>
  </rowResult>

(all data is fabricated test data)

So far so good. But of course I hardcoded the columns to be generated in the XML output; not what I need.

The part where I am stuck is that I am not able to figure out how to programmatically generate the columns.

I have tried several variations of this -

def outputXmlResults(List columns, List resultSet) {

    def builder = new MarkupBuilder(writer)

    builder.queryResults {

        resultSet.each { row ->

            rowResult {

                columns.each { col ->

                    col(row[col])
                }
            }
        }
    }

But no matter what I try nothing works. It almost seems as though I need to generate the code and then "eval" it. I even tried that approach but it got ugly quickly and seemed like the wrong approach. This looks tantalizingly simple and I will probably feel pretty lame once I see the solution but hoping someone might be able to help me out here.


Solution

  • You just want "$col"(row[col]) as this example shows (for just one row):

    import groovy.xml.MarkupBuilder
    
    def cols = ['a', 'b', 'c']
    def row = [a: 42, b: 52, c: 62]
    new MarkupBuilder().with {
        queryResults {
            rowResult {
                cols.each { col ->
                    "$col"(row[col])
                }
            }
        }
    }