Uploaded image for project: 'Groovy'
  1. Groovy
  2. GROOVY-6125

Bugs in GPathResult.parent() and '..' notation

    XMLWordPrintableJSON

    Details

    • Type: Bug
    • Status: Closed
    • Priority: Major
    • Resolution: Fixed
    • Affects Version/s: 2.1.3
    • Fix Version/s: 2.2.0-beta-1
    • Component/s: XML Processing
    • Labels:
    • Environment:
      JDK 6
    • Flags:
      Patch

      Description

      The XmlSlurper sample from the documentation

          <records>
            <car name='HSV Maloo' make='Holden' year='2006'>
              <country>Australia</country>
              <record type='speed'>Production Pickup Truck with speed of 271kph</record>
            </car>
            <car name='P50' make='Peel' year='1962'>
              <country>Isle of Man</country>
              <record type='size'>Smallest Street-Legal Car at 99cm wide and 59 kg in weight</record>
            </car>
            <car name='Royale' make='Bugatti' year='1931'>
              <country>France</country>
              <record type='price'>Most Valuable Car at $15 million</record>
            </car>
          </records>
      

      fails these additional asserts:

          assert records.car.record.findAll({it.@type == 'price'}).parent().country == 'France'
          assert records.car.country.findAll({it == 'Australia'}).'..'.record.@type == 'speed'
      

      On on an XML, where some 'cars' don't have a 'country' child this expression will still return all countries: records.cars.country.parent(). It should only return 'cars' with at least one 'country' child.

      Fixing the problem involved:

      • Adding a public parent() method and parent private property to Node
      • Implementing an additional subclass NodeParents of GPathResult
      • Simplifying childNodes() in NodeChildren, so that it utilizes the classes nodeIterator()
      • Implementing ParentNodes with a nodeIterator() override
      • Cleaning up FilteredNode children to follow the same pattern
      • Instantiating ParentNodes in GPathResult.parent()
      • Calling parent() for property '..'

      And as an added refinement to the GPath syntax:

      • Defining GPathResult.getAt(closure) to call findAll(closure)

      All changed source code in groovy.util.slurpersupport is in the attached zip. The groovy source contains the asserts. All of which pass.

      This fix supersedes the proposed fix for #6122

        Attachments

        1. NewGroovyClass.groovy
          3 kB
          Jochen Eddelbuettel
        2. slurpersupport.zip
          11 kB
          Jochen Eddelbuettel

          Activity

            People

            • Assignee:
              paulk Paul King
              Reporter:
              eddelplus Jochen Eddelbuettel
            • Votes:
              0 Vote for this issue
              Watchers:
              3 Start watching this issue

              Dates

              • Created:
                Updated:
                Resolved: