user3686599
user3686599

Reputation: 13

How to modify XML node attribute using XMLSlurper

I am trying to rename the parent and child node and code something like this,

    def xml = (''' <resultset columns="13" rows="2">
    <row number="1">
    <enterpise>DE</enterpise>
    <line>0001</line>
    <name>DELL</name>
    <version>0.01</version>
    <updtae isnull="true"/>
    </row>
    <row number="2">
    <enterpise>DF</enterpise>
    <line>0002</line>
    <name>DELL</name>
    <version>0.01</version>
    <updtae isnull="true"/>
    </row>
    </resultset>
    ''')
def resultset = new XmlSlurper().parseText(xml) 
def record = resultset.record.find{ it.@columns=='13'}.each 
{ p -> p.attributes().13('columns') } 
resultset.row.replaceNode { row { tr { td("DE") } tr { td("0001") } } }

The expected result is

<Row ss:AutoFitHeight="0">
    <tr><td ss:Type="String">DE</td></tr>
    <tr><td ss:Type="Number">0001</td></tr>
    <tr><td ss:Type="Sring">DELL</td></tr>
    <tr><td ss:Type="Number">0.01</td></tr>
    <tr><td ss:Type="String"></td></tr>
</Row>
<Row ss:AutoFitHeight="0">
    <tr><td ss:Type="String">DF</td></tr>
    <tr><td ss:Type="Number">0002</td></tr>
    <tr><td ss:Type="Sring">DELL</td></tr>
    <tr><td ss:Type="Number">0.01</td></tr>
    <tr><td ss:Type="String"></td></tr>
</Row>

I am unable to remove the parent (resultset) tag and instead of passing the value 'DE' or '0001', i need to get it dynamically. Can you pls help me to complete this

Upvotes: 0

Views: 362

Answers (1)

Matias Bjarland
Matias Bjarland

Reputation: 4482

The following code:

import groovy.xml.* 

def inData = '''
<resultset columns="13" rows="2">
   <row number="1">
     <enterpise>DE</enterpise>
     <line>0001</line>
     <name>DELL</name>
     <version>0.01</version>
     <updtae isnull="true"/>
   </row>
   <row number="2">
     <enterpise>DF</enterpise>
     <line>0002</line>
     <name>DELL</name>
     <version>0.01</version>
     <updtae isnull="true"/>
   </row>
 </resultset>'''

def inXml = new XmlSlurper().parseText(inData)

def outData = new StringWriter()
def outXml = new MarkupBuilder(outData)

inXml.row.each { row -> 
  outXml.Row('ss:AutoFitHeights': 0) {
    tr { td('ss:Type': 'String', row.enterpise) }
    tr { td('ss:Type': 'Number', row.line)       }
    tr { td('ss:Type': 'String', row.name) }
    tr { td('ss:Type': 'Number', row.version) }
    tr { td('ss:Type': 'String') }
  }
}

println outData

when run, produces the following output:

─➤ groovy solution.groovy
output:
<Row ss:AutoFitHeights='0'>
  <tr>
    <td ss:Type='String'>DE</td>
  </tr>
  <tr>
    <td ss:Type='Number'>0001</td>
  </tr>
  <tr>
    <td ss:Type='String'>DELL</td>
  </tr>
  <tr>
    <td ss:Type='Number'>0.01</td>
  </tr>
  <tr>
    <td ss:Type='String' />
  </tr>
</Row>
<Row ss:AutoFitHeights='0'>
  <tr>
    <td ss:Type='String'>DF</td>
  </tr>
  <tr>
    <td ss:Type='Number'>0002</td>
  </tr>
  <tr>
    <td ss:Type='String'>DELL</td>
  </tr>
  <tr>
    <td ss:Type='Number'>0.01</td>
  </tr>
  <tr>
    <td ss:Type='String' />
  </tr>
</Row>

which I think is pretty close to what you are trying to create. In general, if your are trying to do a transformation, not just remove a node, it is easier to create a whole new xml document as in the code above.

Upvotes: 0

Related Questions