真正删除 XMLParser Object Groovy 中的节点
如何通过 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)
似乎可行,但是!!!! 当我将其翻译为我的问题时,它仍然保存原始的 xml,尽管在运行删除方法后返回 true。
我用谷歌搜索了一下,发现了这个BUG。看来我现在受到了影响。我该如何解决它?有没有解决方法,或者我必须回到根源并开始按行复制它......? groovy 在这里真的很不好吗 :-/
编辑:正如下面所写的,并从中获得了经验,不可能以这种方式删除等于“e”的标签。仅第一条记录将被删除。我认为xml格式有问题。没有所需的格式:
并采用
有人能够重现这个错误吗?
edit2:我使用的是 GroovyConsole 1.8.0。将 c3 属性添加到示例中。尝试用相同的方法删除它,同样的错误:第一个 B 部分被删除...... 现在最令人印象深刻的错误:用其他代码尝试:
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)
结果第一部分的属性 c3 更改为 3 ?!?!?!?!? wtf...
我现在正在尝试寻找解决方案一个星期,这真是太累了...
有人有想法吗?
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?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
删除节点的工作方式与其他 DOM API 非常相似。您必须将要删除的节点传递给其父节点的删除方法。
另外,
=
运算符是 Groovy 中的赋值运算符。it.@C1 = 'a'
会将'a'
分配给每个B
节点的C1
属性该文件。由于该赋值的结果是'a'
,它被 Groovy 强制为true
,因此find
将始终返回它遇到的第一个节点。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 theC1
attribute of eachB
node in the document. Since the result of that assignment is'a'
, which is coerced totrue
by Groovy,find
will always return the first node it encounters.改进Justin Piper的解决方案,并提供一个完整的工作示例:
Improving solution of Justin Piper, with a fully working example: