Based on all the good examples provided by http://groovy.codehaus.org/ I’v managed to create a Groovy script that do

  • Find all elements with a name attribute prefixed with ‘DEV_’
  • For all found elements, search for element with identical name attribute, but without prefix ‘DEV_’. If element found, remove it
  • Create a copy of the element with the ‘DEV_’ prefix and then
    • Remove the prefix
    • Change the value of the attribute driver
    • Add the copy to the list of cars
  • Write the updated XML to file

Click more to view the script. Sorry for the limited display of code in my blog.
[teaserbreak]


import groovy.xml.DOMBuilder
import groovy.xml.dom.DOMCategory
import groovy.xml.dom.DOMUtil

class CarExamples {
static def CAR_RECORDS = '''
    <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>
  '''}

def reader  = new StringReader(CarExamples.CAR_RECORDS)
def doc     = DOMBuilder.parse(reader)
def records = doc.documentElement

use (DOMCategory) {

	println "There are " + records.'*'.size() + " cars defined in the file"
    def cars = records.'car'
	println "The parent element for cars are " + cars[0].parent().getTagName()
    def dev_cars = cars.findAll{it."@name".startsWith("DEV_")}
	println " "
	dev_cars.each {
		def nameofdev = it."@name"
		println "Dev name: " + nameofdev
		def stringArr = nameofdev.split("DEV_")
		def deleteMeName = stringArr[1]
		println "Node to remove has name: " + deleteMeName
		def deleteRecord = cars.find{ it.'@name' == deleteMeName }
		if (null != deleteRecord) {
			records.removeChild(deleteRecord)
		}
		def copyOfDev = it.cloneNode(true)
		copyOfDev.setAttribute("name", deleteMeName)
		copyOfDev.setAttribute("driver", "racer")
		records.appendChild(copyOfDev)
		println "\n"
	}
}

outputFile = new File("resultfile.xml")
outputFile.write(DOMUtil.serialize(records))