2. GPath

String books
<response version-api="2.0">
    <value>
        <books>
            <book available="20" id="1">
                <title>Don Quixote</title>
                <author id="1">Miguel de Cervantes</author>
            </book>
            <book available="14" id="2">
                <title>Catcher in the Rye</title>
               <author id="2">JD Salinger</author>
           </book>
           <book available="13" id="3">
               <title>Alice in Wonderland</title>
               <author id="3">Lewis Carroll</author>
           </book>
           <book available="5" id="4">
               <title>Don Quixote</title>
               <author id="4">Miguel de Cervantes</author>
           </book>
       </books>
   </value>
</response>

2.2. Flexible navigation with children (*), depthFirst (**) and breadthFirst

def response = new XmlSlurper().parseText(books)

// .'*' could be replaced by .children()
def catcherInTheRye = response.value.books.'*'.find { node ->
    // node.@id == 2 could be expressed as node['@id'] == 2
    node.name() == 'book' && node.@id == '2'
}

assert catcherInTheRye.title.text() == 'Catcher in the Rye'

def response = new XmlSlurper().parseText(books)

// .'**' could be replaced by .depthFirst()
def bookId = response.'**'.find { book ->
    book.author.text() == 'Lewis Carroll'
}.@id

assert bookId == 3

def response = new XmlSlurper().parseText(books)

def titles = response.'**'.findAll { node -> node.name() == 'title' }*.text()

assert titles.size() == 4

def response = new XmlSlurper().parseText(books)
def nodeName = { node -> node.name() }
def withId2or3 = { node -> node.@id in [2, 3] }

assert ['book', 'author', 'book', 'author'] ==
        response.value.books.depthFirst().findAll(withId2or3).collect(nodeName)
assert ['book', 'book', 'author', 'author'] ==
        response.value.books.breadthFirst().findAll(withId2or3).collect(nodeName)

def response = new XmlSlurper().parseText(books)

def titles = response.value.books.book.findAll { book ->
    /* You can use toInteger() over the GPathResult object */
    book.@id.toInteger() > 2
}*.title

assert titles.size() == 2