Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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

Tags:

xml

groovy

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.

like image 556
flyisland Avatar asked Oct 22 '08 08:10

flyisland


People also ask

How do you delete a node in XML?

To remove a node from the XML Document Object Model (DOM), use the RemoveChild method to remove a specific node. When you remove a node, the method removes the subtree belonging to the node being removed; that is, if it is not a leaf node.

What do you do next to delete the XML node?

Remove a Text Node xml is loaded into xmlDoc. Set the variable x to be the first title element node. Set the variable y to be the text node to remove. Remove the element node by using the removeChild() method from the parent node.

Which of the following method is used to write an XML document in groovy?

XML Parser − The Groovy XmlParser class employs a simple model for parsing an XML document into a tree of Node instances. Each Node has the name of the XML element, the attributes of the element, and references to any child Nodes. This model is sufficient for most simple XML processing.


2 Answers

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>
like image 58
flyisland Avatar answered Sep 27 '22 18:09

flyisland


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>
like image 34
Ted Naleid Avatar answered Sep 27 '22 18:09

Ted Naleid