0

i have a xml from where i wish to remove few nodes. The idea i used is to run through all the root node children and keep writing to another file those nodes which i dont need to delete.

One problem I see is: the node attributes gets reordered in the written file which i dont want

my code looks like:

def xml = new XmlSlurper(false, false).parse(args[0])
ant.delete(file:fileName)
File f = new File(fileName)
xml.children().each{
     String str = it.@name
     if(some condiotion == false)
        f << groovy.xml.XmlUtil.serialize(it)

}

another problem is that in the begining of every node it inserts

<?xml version="1.0" encoding="UTF-8"?>
Vik
  • 8,721
  • 27
  • 83
  • 168

2 Answers2

0

There is no concrete example of the xml present in the question. Here is an example how a Node can be removed:

import groovy.xml.XmlUtil

def xml = '''
<School>
    <Classes>
        <Class>
           <Teachers>
              <Name>Rama</Name>
              <Name>Indhu</Name>
           </Teachers>
           <Name>Anil</Name>
           <RollNumber>16</RollNumber>
        </Class>
        <Class>
            <Teachers>
              <Name>Nisha</Name>
              <Name>Ram</Name>
           </Teachers>
           <Name>manu</Name>
           <RollNumber>21</RollNumber>
        </Class>
   </Classes>
</School>
'''

def parsed = new XmlSlurper().parseText( xml )

parsed.'**'.each { 
    if(it.name() == 'Teachers') {
        it.replaceNode { }
    }
}

XmlUtil.serialize( parsed )

In the above example, Teachers node is removed by doing a depthFirst search and iterating over each node and finally using replaceNode with an empty Closure. I hope this can be used as the logic you want.

PS: I have omitted the File operations for brevity.

dmahapatro
  • 49,365
  • 7
  • 88
  • 117
0

The API work with a replacementStack. So, the replaceNode {} will show the result only when you serialize the node like:

    GPathResult body = parsePath.Body
    int oldSize = parsePath.children().size()

    body.list()
    body[0].replaceNode {} // Remove o no, mas não será visivel para o objeto pai, somente no momento de serializacao. Pois a API adiciona em uma pilha de alteracao que será usada na serializacao

    String newXmlContent = XmlUtil.serialize(parsePath)
    GPathResult newParsePath = new XmlSlurper().parseText(newXmlContent)
    int newSize = newParsePath.children().size()

    assertNotNull(this.parsePath)
    assertEquals(2, oldSize)
    assertEquals(1, newSize)
    assertTrue(newSize < oldSize)
    assertNotNull(body)
Alex Ferreira
  • 38
  • 1
  • 10