tags:

views:

1926

answers:

3

for example, I have the following xml document:

 def CAR_RECORDS = '''
    <records>
      <car name='HSV Maloo' make='Holden' year='2006'/>
      <car name='P50' make='Peel' year='1962'/>
      <car name='Royale' make='Bugatti' year='1931'/>
    </records>
  '''

and I want to move the car "Royale" up to first one, and insert a new car just after car"HSV Maloo", the result would be:

'''
    <records>
      <car name='Royale' make='Bugatti' year='1931'/>
      <car name='HSV Maloo' make='Holden' year='2006'/>
      <car name='My New Car' make='Peel' year='1962'/>
      <car name='P50' make='Peel' year='1962'/>
    </records>
  '''

How to do it with Groovy? comments are welcome.

A: 

<hand-wave> these are not the codz you seek </hand-wave>

Node root = new XmlParser().parseText(CAR_RECORDS)
NodeList carNodes = root.car
Node royale = carNodes[2]
carNodes.remove(royale)
carNodes.add(0, royale)
carNodes.add(2, new Node(root, 'car', [name:'My New Card', make:'Peel', year:'1962']))

I don't know if there's a smarter way to create new nodes... but that works for me.

EDIT: uhg... thanks guys... I got lazy and was printing carNodes when i tested this instead of the root... yikes.

danb
Hi danb, I try to print it with XmlNodePrinter, but it appears in wrong order.<records> <car year="2006" make="Holden" name="HSV Maloo"/> <car year="1962" make="Peel" name="P50"/> <car year="1931" make="Bugatti" name="Royale"/> <car name="My New Card" make="
flyisland
I was just about to say the same thing...it looks like it's reordering the items in the NodeList, but that isn't reflected in how the root node gets iterated by the XmlNodePrinter.
Ted Naleid
yup... I was way sloppy. thanks!
danb
+3  A: 

I went down a similar route to danb, but ran into problems when actually printing out the resulting XML. Then I realized that the NodeList that was returned by asking the root for all of it's "car" children isn't the same list as you get by just asking for the root's children. Even though they happen to be the same lists in this case, they wouldn't always be if there were non "car" children under the root. Because of this, reording the list of cars that come back from the query doesn't affect the initial list.

Here's a solution that appends and reorders:

def CAR_RECORDS = '''
   <records>
     <car name='HSV Maloo' make='Holden' year='2006'/>
     <car name='P50' make='Peel' year='1962'/>
     <car name='Royale' make='Bugatti' year='1931'/>
   </records>
 '''

def carRecords = new XmlParser().parseText(CAR_RECORDS)

def cars = carRecords.children()
def royale = cars.find { it.@name == 'Royale' } 
cars.remove(royale)
cars.add(0, royale)
def newCar = new Node(carRecords, 'car', [name:'My New Car', make:'Peel', year:'1962'])

assert ["Royale", "HSV Maloo", "P50", "My New Car"] == carRecords.car*.@name

new XmlNodePrinter().print(carRecords)

The assertion with the propertly ordered cars passes, and the XmlNodePrinter outputs:

<records>
  <car year="1931" make="Bugatti" name="Royale"/>
  <car year="2006" make="Holden" name="HSV Maloo"/>
  <car year="1962" make="Peel" name="P50"/>
  <car name="My New Car" make="Peel" year="1962"/>
</records>
Ted Naleid
+3  A: 

ted, maybe you did not notice that I wanted to '''insert a new car just after car"HSV Maloo"''', so I modify your code to :

def newCar = new Node(null, 'car', [name:'My New Car', make:'Peel', year:'1962'])
cars.add(2, newCar)

new XmlNodePrinter().print(carRecords)

now, it works with proper order! thanks to danb & ted.

<records>
  <car year="1931" make="Bugatti" name="Royale"/>
  <car year="2006" make="Holden" name="HSV Maloo"/>
  <car name="My New Car" make="Peel" year="1962"/>
  <car year="1962" make="Peel" name="P50"/>
</records>
flyisland
Yep, I missed that, oops :). I was thinking that you wanted it last, but the code you have is correct for getting it in the 3rd place.
Ted Naleid