真正删除XMLParser Object Groovy中的节点

问题描述 投票:3回答:2

如何通过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)

似乎可以工作!!!!当我将其翻译成我的问题时,它仍然保存了运行remove-method后返回true的原始xml althoguh。

我用Google搜索了一下,发现了这个BUG。似乎我现在对此有所影响。我该如何解决?有没有解决方法,还是我必须回到根源并开始逐行复制...? groovy在这里真的很不时髦:-/

[edit:如下所述,并从中获得了经验,无法以这种方式删除等于'e'的标记。仅第一个记录将被删除。我认为xml格式有问题。没有所需的格式:

<A x='1' y='2'></A>

并且采用格式

<A> <x>1</x> <y>2</y> </A>

有人能够重现此错误吗?

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 ...

我现在想寻找一个星期的解决方案,这很累...

有人有主意吗?

xml groovy xml-parsing
2个回答
12
投票

删除节点的工作原理非常类似于其他DOM API。您必须将要删除的节点传递给其父节点的remove方法。

=运算符也是Groovy中的赋值运算符。 it.@C1 = 'a'会将'a'分配给文档中每个C1节点的B属性。由于该分配的结果为'a',由Groovy强制将其转换为true,因此find将始终返回其遇到的第一个节点。

xml=new XmlParser().parseText(x)
def nodeToDel=xml.A.B.C1.find { it.text() == 'a' }
def parent = nodeToDel.parent()
parent.remove(nodeToDel)

0
投票

使用完整的示例改进Justin Piper的解决方案:

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
© www.soinside.com 2019 - 2024. All rights reserved.