Versions Compared

Key

  • This line was added.
  • This line was removed.
  • Formatting was changed.

...

Code Block
// requires dom4j.jar
import org.dom4j.io.SAXReader

def reader   = new StringReader(XmlExamples.CAR_RECORDS)
def records  = new SAXReader().read(reader).rootElement
def messages = []

records.elementIterator().each{ car ->
    def make = car.attributeValue('make')
    def country = car.elementText('country')
    def type = car.element('record').attributeValue('type')
    messages << make + ' of ' + country + ' has a ' + type + ' record'
}

assert messages == [
    'Holden of Australia has a speed record',
    'Peel of Isle of Man has a size record',
    'Bugatti of France has a price record'
]

DOM4J also supports a streaming mode which lets you manually prune parts of the DOM tree during processing to facilitate processing large documents. Here is an example which uses DOM4J in that mode:

Code Block

// requires dom4j.jar
import org.dom4j.io.SAXReader
import org.dom4j.*

class PruningCarHandler implements ElementHandler {
    def messages = []
    public void onStart(ElementPath path) { }
    public void onEnd(ElementPath path) {
        def car = path.current
        def make = car.attributeValue('make')
        def country = car.elementText('country')
        def type = car.element('record').attributeValue('type')
        messages << make + ' of ' + country + ' has a ' + type + ' record'
        car.detach()
    }
}

def xml     = new StringReader(XmlExamples.CAR_RECORDS)
def reader  = new SAXReader()
def handler = new PruningCarHandler()

reader.addHandler('/records/car', handler)
reader.read(xml)

assert handler.messages == [
    'Holden of Australia has a speed record',
    'Peel of Isle of Man has a size record',
    'Bugatti of France has a price record'
]

We could have also performed a hybrid approach which pruned away parts of the tree we weren't interested in and then performed tree-walking/navigation style coding after that.