真正删除 XMLParser Object Groovy 中的节点

发布于 2024-12-01 15:43:16 字数 1478 浏览 0 评论 0原文

如何通过 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格式有问题。没有所需的格式:

并采用

格式12

有人能够重现这个错误吗?

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 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

も让我眼熟你 2024-12-08 15:43:16

删除节点的工作方式与其他 DOM API 非常相似。您必须将要删除的节点传递给其父节点的删除方法。

另外,= 运算符是 Groovy 中的赋值运算符。 it.@C1 = 'a' 会将 'a' 分配给每个 B 节点的 C1 属性该文件。由于该赋值的结果是 '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)

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)
你与昨日 2024-12-08 15:43:16

改进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

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
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文