How to insert/move/delete nodes in xml with Groovy? How to insert/move/delete nodes in xml with Groovy? xml xml

How to insert/move/delete nodes in xml with Groovy?


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*.@namenew 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, 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>


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

Node root = new XmlParser().parseText(CAR_RECORDS)NodeList carNodes = root.carNode 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.