- •Credits
- •About the Authors
- •About the Reviewers
- •www.PacktPub.com
- •Table of Contents
- •Preface
- •Introduction
- •Installing Groovy on Windows
- •Installing Groovy on Linux and OS X
- •Executing Groovy code from the command line
- •Using Groovy as a command-line text file editor
- •Running Groovy with invokedynamic support
- •Building Groovy from source
- •Managing multiple Groovy installations on Linux
- •Using groovysh to try out Groovy commands
- •Starting groovyConsole to execute Groovy snippets
- •Configuring Groovy in Eclipse
- •Configuring Groovy in IntelliJ IDEA
- •Introduction
- •Using Java classes from Groovy
- •Embedding Groovy into Java
- •Compiling Groovy code
- •Generating documentation for Groovy code
- •Introduction
- •Searching strings with regular expressions
- •Writing less verbose Java Beans with Groovy Beans
- •Inheriting constructors in Groovy classes
- •Defining code as data in Groovy
- •Defining data structures as code in Groovy
- •Implementing multiple inheritance in Groovy
- •Defining type-checking rules for dynamic code
- •Adding automatic logging to Groovy classes
- •Introduction
- •Reading from a file
- •Reading a text file line by line
- •Processing every word in a text file
- •Writing to a file
- •Replacing tabs with spaces in a text file
- •Deleting a file or directory
- •Walking through a directory recursively
- •Searching for files
- •Changing file attributes on Windows
- •Reading data from a ZIP file
- •Reading an Excel file
- •Extracting data from a PDF
- •Introduction
- •Reading XML using XmlSlurper
- •Reading XML using XmlParser
- •Reading XML content with namespaces
- •Searching in XML with GPath
- •Searching in XML with XPath
- •Constructing XML content
- •Modifying XML content
- •Sorting XML nodes
- •Serializing Groovy Beans to XML
- •Introduction
- •Parsing JSON messages with JsonSlurper
- •Constructing JSON messages with JsonBuilder
- •Modifying JSON messages
- •Validating JSON messages
- •Converting JSON message to XML
- •Converting JSON message to Groovy Bean
- •Using JSON to configure your scripts
- •Introduction
- •Creating a database table
- •Connecting to an SQL database
- •Modifying data in an SQL database
- •Calling a stored procedure
- •Reading BLOB/CLOB from a database
- •Building a simple ORM framework
- •Using Groovy to access Redis
- •Using Groovy to access MongoDB
- •Using Groovy to access Apache Cassandra
- •Introduction
- •Downloading content from the Internet
- •Executing an HTTP GET request
- •Executing an HTTP POST request
- •Constructing and modifying complex URLs
- •Issuing a REST request and parsing a response
- •Issuing a SOAP request and parsing a response
- •Consuming RSS and Atom feeds
- •Using basic authentication for web service security
- •Using OAuth for web service security
- •Introduction
- •Querying methods and properties
- •Dynamically extending classes with new methods
- •Overriding methods dynamically
- •Adding performance logging to methods
- •Adding transparent imports to a script
- •DSL for executing commands over SSH
- •DSL for generating reports from logfiles
- •Introduction
- •Processing collections concurrently
- •Downloading files concurrently
- •Splitting a large task into smaller parallel jobs
- •Running tasks in parallel and asynchronously
- •Using actors to build message-based concurrency
- •Using STM to atomically update fields
- •Using dataflow variables for lazy evaluation
- •Index
Working with XML in Groovy
myTodos,
XPathConstants.NODESET ).each { println it.nodeValue }
//Bonus: print out all tasks
//for which the due date falls in September xpathSaxon.evaluate(
'//task[month-from-date(due)=9]/title/text()', myTodos,
XPathConstants.NODESET ).each { println it.nodeValue }
See also
More information about the XPath query language can be found at http://www.w3.org/TR/xpath. Also, the following links may be useful for further reading:
ff http://www.w3.org/TR/xpath20/ ff http://saxon.sourceforge.net/
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()
184
www.it-ebooks.info
Chapter 5
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.
185
www.it-ebooks.info
Working with XML in Groovy
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:
ff StreamingMarkupBuilder doesn't output the XML until a writer is explicitly passed, while MarkupBuilder, by default, outputs to System.out.
ff 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.
ff MarkupBuilder formats the output for increased readability whereas
StreamingMarkupBuilder does not.
See also
ff Reading XML using XmlSlurper ff Reading XML using XmlParser
ff http://groovy.codehaus.org/Creating+XML+using+Groovy%27s+Marku pBuilder
ff http://groovy.codehaus.org/api/groovy/xml/MarkupBuilder.html
186
www.it-ebooks.info
Chapter 5
ff http://groovy.codehaus.org/gapi/groovy/xml/ StreamingMarkupBuilder.html
Modifying XML content
In this recipe, we will learn how to update and delete nodes of a parsed XML document using the XmlParser.
Getting ready
Let's start by parsing the following XML with the XmlParser (see the Reading XML using XmlParser recipe):
def carXml = '''
<?xml version="1.0" ?> <cool-cars>
<car manufacturer="Ferrari"> <model>430 Scuderia</model>
</car>
<car manufacturer="Porsche"> <model>911</model>
</car>
<car manufacturer="Lotus"> <model>Elan</model>
</car>
<car manufacturer="Pagani"> <model>Huayra</model>
</car> </cool-cars>
'''
def coolCars = new XmlParser().parseText(carXml)
How to do it...
The simplest way to change the value of a node is to reference it using the position of the node itself.
1.For instance, if we want to change the model of the Lotus brand to Elise, we can reference the model node as showed in the example:
coolCars.car[2].model[0].value = 'Elise'
187
www.it-ebooks.info
Working with XML in Groovy
2.Alternatively, it is possible to find a node by its contents and alter it:
coolCars.find { it.@manufacturer == 'Ferrari'
}.model[0].value = 'Testarossa'
Instead of referencing the node by its position, we use the find method to reference the attribute of the node.
3.What about modifying an attribute of a node? coolCars.car[1].@manufacturer = 'Ford'
4.Finally, to delete nodes, you can use a very similar approach:
coolCars.remove(coolCars.car[3])
coolCars.remove(coolCars.car[1]) or even better:
coolCars.findAll { it.@manufacturer.startsWith('P') }
.each |
{ coolCars.remove(it) } |
This previous example deletes every car's manufacturer, whose name starts with the letter P.
5.Now we can print the result:
new XmlNodePrinter().print(coolCars)
6.The output will be as follows:
<cool-cars>
<car manufacturer="Ferrari"> <model>
Testarossa </model>
</car>
<car manufacturer="Lotus"> <model>
Elise </model>
</car> </cool-cars>
How it works...
Thanks to Groovy's dynamic typing and metaprogramming capabilities, we can access the members of our document directly by name, as shown in several other recipes from this chapter: Reading XML using XmlSlurper, Searching in XML with GPath, and Constructing XML content.
188
www.it-ebooks.info