Raul Biondo
Raul Biondo

Reputation: 17

How to extract a specific node from a XML & create new xml using groovy

The acutal xml is:

<prnReq>
    <ltrPrnReqs>
        <ltrPrnReq>
            <ltrData>
                <Postal>910060121</Postal>
                <Amt>514.17</Amt>
            </ltrData>
        </ltrPrnReq>
    </ltrPrnReqs>
</prnReq>

The final XML must be only the 'ltrData':

      <ltrData>
            <Postal>910060121</Postal>
            <Amt>514.17</Amt>
      </ltrData>

Below the current code, where I need to create a new file using only the tag, however, the code is not running.

import groovy.xml.QName
import groovy.xml.StreamingMarkupBuilder
import groovy.xml.XmlUtil

def xmlString = """
<prnReq>
    <ltrPrnReqs>
          <ltrPrnReq>
             <ltrData>
                <Postal>910060121</Postal>
                <Amt>514.17</Amt>
            </ltrData>
          </ltrPrnReq>
    </ltrPrnReqs> 
</prnReq>"""


def xml1 = new XmlSlurper().parseText(xmlString) 
def ltrD = xml1.'**'.find{it.name() == 'ltrData'}.text()

def builder = new StreamingMarkupBuilder()
builder.encoding = 'UTF-8'
def xml2 = builder.bindNode (ltrD)

def file1 = new File('C:\\Temp\\out\\ltrData.xml')
assert XmlUtil.serialize(xml2)
file1.write(xml2,'UTF-8'))

Hi @Rao, I've just updated the content. When I try to apply the proposed solution I got an error: "[Fatal Error] :1:1: Premature end of file.". So I believe I'm still doing something wrong getting the content. Could you please have a look how to get the correct syntax to get both new elements above? Many thanks

Upvotes: 1

Views: 1886

Answers (1)

Rao
Rao

Reputation: 21369

You should be able to do it with StreamingMarkupBuilder. And follow the in-line comments:

import groovy.xml.StreamingMarkupBuilder
import groovy.xml.XmlUtil
def xmlString = """<prnReq> 
  <ltrPrnReqs>
     <ltrPrnReq>
        <ltrData>
           <Postal>910060121</Postal>
           <Amt>514.17</Amt>
        </ltrData>
     </ltrPrnReq>
   </ltrPrnReqs>
</prnReq>"""

//Extract the data you needed from existing xml
def xml1 = new XmlSlurper().parseText(xmlString) 
def ltrData1 = xml1.'**'.find{it.name() == 'ltrData'}
def nodes = ltrData1.children()*.name()

//Build the output xml
def xml = new StreamingMarkupBuilder().bind {    
    ltrData { 
       nodes.each { "$it"(ltrData1."$it".text()) }
    }
}
def file = new File('C:/Temp/out/letter_PQC301.xml')
println XmlUtil.serialize(xml)
file.write(XmlUtil.serialize(xml),'UTF-8')
​

You can quickly try the same online demo

EDIT: Optimized solution. Note that below uses without StreamingMarkupBuilder

import groovy.xml.StreamingMarkupBuilder
import groovy.xml.XmlUtil
def xmlString = """<prnReq> 
  <ltrPrnReqs>
     <ltrPrnReq>
        <ltrData>
           <Postal>910060121</Postal>
           <Amt>514.17</Amt>
        </ltrData>
     </ltrPrnReq>
   </ltrPrnReqs>
</prnReq>"""

//Extract the data you needed from existing xml
def xml1 = new XmlSlurper().parseText(xmlString) 
def ltrData1 = xml1.'**'.find{it.name() == 'ltrData'}

def file = new File('C:/Temp/out/letter_PQC301.xml')
println XmlUtil.serialize(ltrData1)
file.write(XmlUtil.serialize(ltrData1),'UTF-8')

Upvotes: 2

Related Questions