Действительно удаление узлов в XMLParser Object Groovy - PullRequest
3 голосов
/ 26 августа 2011

Как ДЕЙСТВИТЕЛЬНО удалить узел через 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 после запуска метода remove.

Я немного погуглил и нашел это BUG . И, похоже, меня это сейчас касается. Как я могу решить это? Есть ли обходной путь, или я должен вернуться к корням и начать копировать его также ... ?? Является ли Groovy действительно ungroovy здесь: - /

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

Я пытаюсь найти решение на неделю, оно довольно утомительно ...

У кого-нибудь есть идея?

1 Ответ

11 голосов
/ 26 августа 2011

Удаление узлов работает почти так же, как и другие DOM API. Вы должны передать узел, который хотите удалить, методу удаления его родителя.

Также оператор = является оператором присваивания в 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)
...