tags:

views:

29

answers:

2

With more than a little help from daviderossi.blogspot.com I have managed to get some code working to replace an xml value with another

This give me the following output which both edits the value at the 'ix' position BUT also adds a second copy at the end. If I search for it with LastIndexOf and delete it then it deletes the first occurrence. Any ideas on why the code might be doing that, or how to mitigate this unwanted effect??

def fm_xml = '''<?xml version="1.0" encoding="UTF-8"?>
<MAlong>
<Enquiry.ID>SC11147</Enquiry.ID>
<student.name_middle></student.name_middle>
<student.name_known></student.name_known>
<student.name_previous></student.name_previous>
<student.name_cert>John REnfrew</student.name_cert>
<student.detail_gender>M</student.detail_gender>
<student.sign_name>John Renfrew</student.sign_name>
<student.sign_date>05/01/2010</student.sign_date>
</MAlong>'''

xml = new XmlParser().parseText(fm_xml)
ix = xml.children().findIndexOf{it.name() =='student.name_middle'}
nn = new Node(xml, 'student.name_middle', "NEW")
if (ix != -1 ) {
xml.children()[ix] = nn
nn.parent = xml
}
writer = new StringWriter()
new XmlNodePrinter(new PrintWriter(writer)).print(xml)
result = writer.toString()

RESULT

<MAlong>
<Enquiry.ID>
 SC11147
</Enquiry.ID>
<student.name_middle>
 NEW
</student.name_middle>
<student.name_known/>
<student.name_previous/>
<student.name_cert>
 John REnfrew
</student.name_cert>
<student.detail_gender>
 M
</student.detail_gender>
<student.sign_name>
 John Renfrew
</student.sign_name>
<student.sign_date>
 05/01/2010
</student.sign_date>
<student.name_middle>
 NEW
</student.name_middle>
</MAlong>
+1  A: 

Using the Groovy class XMLSlurper to work with your XML makes your code easier and improves readability. I created a sample script at the Groovy Console where you can evaluate this:

Example-Code

import groovy.xml.StreamingMarkupBuilder
import groovy.xml.XmlUtil

def prettyprint(xml) {
  XmlUtil.serialize(new StreamingMarkupBuilder().bind { mkp.yield xml })
}

def input = '''<?xml version="1.0" encoding="UTF-8"?><MAlong>
<Enquiry.ID>SC11147</Enquiry.ID>
<student.name_middle></student.name_middle>
<student.name_known></student.name_known>
<student.name_previous></student.name_previous>
<student.name_cert>John REnfrew</student.name_cert>
<student.detail_gender>M</student.detail_gender>
<student.sign_name>John Renfrew</student.sign_name>
<student.sign_date>05/01/2010</student.sign_date>
</MAlong>'''

def root = new XmlSlurper().parseText(input)
println "Input\n" + prettyprint(root)

// static way
root.'student.name_middle' = "MIDDLE NAME"

// variable way
root.setProperty("student.name_previous", "PREVIOUS NAME")

println "Output\n" + prettyprint(root​)​

Reference:

codescape
neater, much easier to read, but it throws an error:[student.name_middle] is a constant expression, but it should be a variable expressionWould like to explore this as it seems very efficient.<br/>Fixed the repeating values by making itnn = new Node(null, 'student.name_middle', "NEW")
john renfrew
The above script should work as it is. I added a second modification statement showing modification of fields with dynamic names.
codescape
The output from that produces a single line. Is there a way to recreate the tree with markupbuilder??
john renfrew
Yes, you can do it this way: `println XmlUtil.serialize(new StreamingMarkupBuilder().bind { mkp.yield root })​` and remember to `import groovy.xml.XmlUtil`
codescape
Changed above code to show the usage.
codescape
A: 

That works fine now. Many thanks....

j renfrew
Perfect.!. Just makes it easier to read and therefore check errors.Thankyou for the input.
j renfrew