Constructing XML content

The previous Reading XML using XmlSlurper, Reading XML using XmlParser, and Searching in XML with GPath recipes have been useful to learn the ingredients and the techniques for consuming and querying XML documents. In this recipe, we will cover how to produce XML using Groovy's MarkupBuilder.

How to do it...

Let's create a bibliography XML similar to the one we used in the Reading XML using XmlSlurper recipe.

  1. In order to start using MarkupBuilder, you first need to import it since it's not available by default:
    import groovy.xml.MarkupBuilder
  2. Then you need to create a writer object that will be responsible for the final output of the XML content. For the sake of simplicity let's use:
    java.io.StringWriter:
    def writer = new StringWriter()
  3. Finally, we need to create an instance of MarkupBuilder and pass the writer object to it:
    def xml = new MarkupBuilder(writer)
  4. At this point, we are ready to create some XML:
    xml.bibliography {
      author('William Shakespeare')
      play {
        year('1595')
        title('A Midsummer-Night's Dream.')
      }
    }
  5. And now, by printing our writer object:
    println writer

    We'll get the following output:

    <bibliography>
      <author>William Shakespeare</author>
      <play>
        <year>1595</year>
        <title>A Midsummer-Night's Dream.</title>
      </play>
    </bibliography>

How it works...

The previous XML construction code is a set of nested dynamic method calls that are mapped directly to XML element names. String parameter passed to those methods defines the content of the element (for example, author('William Shakespeare')).

All the magic happens behind the scenes with the help of Groovy's Meta Object Protocol (MOP), which is heavily used by MarkupBuilder (and in general, any other builder class within Groovy, see the Defining data structures as code in Groovy recipe in Chapter 3, Using Groovy Language Features). Every object in Groovy extends from groovy.lang.GroovyObject, which offers two methods: invokeMethod and getProperty. Those methods are overridden by MarkupBuilder to handle dynamic method names that are translated into an XML tree.

It is possible to construct any kind of markup with this approach including HTML/XHTML.

There's more...

Another way to create XML content is by using the groovy.xml.StreamingMarkupBuilder class. Its API is similar, but a bit more complex than the MarkupBuilder API. On the other hand, it offers better memory management and allows creating large XML files with minimal memory footprint:

import groovy.xml.StreamingMarkupBuilder
def builder = new StreamingMarkupBuilder()
def bibliography = builder.bind {
  bibliography {
    author('William Shakespeare')
    play {
      year('1595')
      title('A Midsummer-Night's Dream.')
    }
  }
}
println bibliography

The previous code snippet achieves a similar result to the initial example.

In general, MarkupBuilder to StreamingMarkupBuilder is the same as XmlParser (see the Reading XML using XmlParser recipe) is to XmlSlurper (see the Reading XML using XmlSlurper recipe). There are three main differences between MarkupBuilder and StreamingMarkupBuilder:

  • StreamingMarkupBuilder doesn't output the XML until a writer is explicitly passed, while MarkupBuilder, by default, outputs to System.out.
  • MarkupBuilder processes the XML generation synchronously while StreamingMarkupBuilder generates the XML only when is passed to a Writer. It is possible, for instance, to define a number of closures containing snippets of XML and generate the markup only when needed.
  • MarkupBuilder formats the output for increased readability whereas StreamingMarkupBuilder does not.
..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
3.21.100.62