Really deleting nodes in XMLParser Object Groovy
How to REALLY remove a node via XMLParser:
x='''<X>
<A>
<B c3='1'>
<C1>a</C1>
<C2>b</C2>
</B>
<B c3='2'>
<C1>e</C1>
<C2>e</C2>
</B>
<B c3='3'>
<C1>f</C1>
<C2>f</C2>
</B>
</A>
</X>
'''
xml=new XmlParser().parseText(x)
def nodeToDel=xml.A.B.find{it.@C1='a'}
xml.remove(nodeToDel)
println xml
new XmlNodePrinter(new PrintWriter(new FileWriter(new File('c:/temp/a.xml')))).print(xml)
Seems to work BUT!!!! as i translated this to my problem it still saves the original xml althoguh returning true after running remove-method.
I googled a little bit and found this BUG. And it seems as i am affected now of that. How can i solve it? Is there a workaround, or do i have to get back to the roots and start to copying it linewise...?? Is groovy really ungroovy here :-/
edit: As written below, and got experience from that, it is not possible to remove the tag where equals 'e' this way. Only the first Record will be removed. I think there is a problem with the xml format. Not having the needed format:
<A x='1' y='2'></A>
and having it in the format
<A> <x>1</x> <开发者_开发百科;y>2</y> </A>
Is somebody able to reproduce this bug?
edit2: I am using the GroovyConsole 1.8.0. Added the c3 attributes to the example. Tried to remove it with same method, same bug: The first B section was removed... Now the most impressing bug: Tried it with other code:
def xml=new XmlParser().parseText(x)
xml.A.remove(xml.A.B.find{it.@'c3'= '3'}) //want to remove third section
new XmlNodePrinter(new PrintWriter(new FileWriter(new File('c:/temp/a.xml')))).print(xml)
results that the first section the property c3 is changed to 3 ?!?!?!?!? wtf...
I am trying to find a solution for a week now, it is quite exhausting...
Somebody an idea?
Removing nodes works pretty much like other DOM APIs. You have to pass the node you want to delete to the remove method of its parent.
Also the =
operator is the assignment operator in Groovy. it.@C1 = 'a'
would assign 'a'
to the C1
attribute of each B
node in the document. Since the result of that assignment is 'a'
, which is coerced to true
by Groovy, find
will always return the first node it encounters.
xml=new XmlParser().parseText(x)
def nodeToDel=xml.A.B.C1.find { it.text() == 'a' }
def parent = nodeToDel.parent()
parent.remove(nodeToDel)
Improving solution of Justin Piper, with a fully working example:
def xml = new XmlParser().parseText('''
<root>
<element id="10" />
<element id="20" />
</root>
''')
def nodeToDel = xml.find { it["@id"] == '20' }
if (nodeToDel) {
nodeToDel.parent().remove(nodeToDel)
}
println xml
精彩评论