title: Nested GPath expressions with XmlSlurper and findAll
body: <p>I'm trying to analyse an XML tree using <code>XmlSlurper</code> and GPath, and the behaviour of the <code>findAll</code> method confuses me.</p>
  
  <p>Say, for example, that you have the following XML tree:</p>
  
  <pre><code>&lt;html&gt;
      &lt;body&gt;
          &lt;ul&gt;
              &lt;li class="odd"&gt;&lt;span&gt;Element 1&lt;/span&gt;&lt;/li&gt;
              &lt;li class="even"&gt;&lt;span&gt;Element 2&lt;/span&gt;&lt;/li&gt;
              &lt;li class="odd"&gt;&lt;span&gt;Element 3&lt;/span&gt;&lt;/li&gt;
              &lt;li class="even"&gt;&lt;span&gt;Element 4&lt;/span&gt;&lt;/li&gt;
              &lt;li class="odd"&gt;&lt;span&gt;Element 5&lt;/span&gt;&lt;/li&gt;
          &lt;/ul&gt;
      &lt;/body&gt;
  &lt;/html&gt;
  </code></pre>
  
  <p>Assuming that <code>xml</code> has been initialised through one of <code>XmlSlurper</code>'s <code>parse</code> methods, the following code executes as one would expect:</p>
  
  <pre><code>// Prints:
  // odd
  // odd
  // odd
  xml.body.ul.li.findAll {it.@class == 'odd'}.@class.each {println it.text()}
  </code></pre>
  
  <p>On the other hand:</p>
  
  <pre><code>// Doesn't print anything.
  xml.body.ul.li.findAll {it.@class == 'odd'}.span.each {println it.text()}
  </code></pre>
  
  <p>I'm struggling to understand why I can use the special <code>@</code> property (as well as others, such as <code>**</code>), but not 'normal' ones.</p>
  
  <p>I've looked at the API code, and what confuses me even more is that the <code>getProperty</code> implementation (found in <code>GPathResult</code>) seems to support what I'm trying to do.</p>
  
  <p>What am I missing?</p>