AnsweredAssumed Answered

Using a Groovy script within a data process to reorganize an XML

Question asked by AdamBlakely4561 on Dec 5, 2016
Latest reply on Aug 19, 2017 by saimaniteja.suda449785

Jake Rauch and I are trying to use the below script to reorganize the structure of our XML within Boomi.  One of the engineers created this script with Groovy, but she did not create the script within Boomi.  The script is success when not used in Boomi, however, when we tried to incorporate it into one of our processes, it doesn't work.  the process gets through half of the script and it seems like it stops performing the script when it starts attempting to write it out (when 'BufferedOutputStream output' is declared).  I'm not sure if the first half actually performs the script, but it finishes the data process component shape and continues with the rest of the process.  I'm looking for some suggestions for getting this script to successfully run.

 

 

import groovy.util.slurpersupport.GPathResult
import groovy.xml.MarkupBuilder
import groovy.xml.StreamingMarkupBuilder

 

println new Date()
println Runtime.getRuntime().totalMemory() - Runtime.getRuntime().freeMemory()
List<String> listOfSnapshots = []

Scanner scan = new Scanner(new File("D:\\Boomi Data Files\\554A0353-1394-4C88-9F13-408FD0A0C416.xml"))
scan.useDelimiter("(?=<ns2:SnapshotData )")

boolean snapshotSection = false

List<String> sponsorOids
while (scan.hasNext()) {
if (!snapshotSection) {
// Get rid of header stuff
String starterInfo = scan.next().concat("</Snapshots></ns2:BFedi>")
def processingInfoNode = new XmlParser().parseText(starterInfo)
String sponsorOidsString = processingInfoNode."ns2:ProcessingInfo".Parameters.'*'.find { Parameter ->
Parameter.Name.text() == "SPONSOROIDS"
}.Value.text()
sponsorOids = sponsorOidsString.split(",")

println "Oids " + sponsorOidsString + " " + sponsorOids.size()
snapshotSection = true
} else {
String snapshot = scan.next();
if (!snapshot.endsWith("</ns2:SnapshotData>")) {
String[] lastLineSplit = snapshot.split("</Snapshots>")
snapshot = lastLineSplit[0]
}
listOfSnapshots.add(snapshot)
}
}
scan.close()

BufferedOutputStream output = new BufferedOutputStream(new FileOutputStream("D:\\Boomi Data Files\\out.xml"))
output.write("<sponsors>".getBytes())
sponsorOids.each { sponsorOid ->

List<String> sponsorsSnapshots = listOfSnapshots.findAll { it.contains('ReferenceId="' + sponsorOid + '"')}

boolean firstSponsor = true
String endOfSponsor = ""
sponsorsSnapshots.each { snapshot ->
Node snapshotNode = new XmlParser().parseText(snapshot)
def sponsor = snapshotNode.Sponsor[0]
snapshotNode.remove(sponsor)

if(firstSponsor) {
StringWriter xmlOutput = new StringWriter()
XmlNodePrinter xmlNodePrinter = new XmlNodePrinter(new PrintWriter(xmlOutput))
xmlNodePrinter.print(sponsor)
String sponsorString = xmlOutput.toString()
def sponsorStringList = sponsorString.split("(?=</Sponsor>)")
output.write((sponsorStringList[0]+"<SnapShotDataSets>").getBytes())
endOfSponsor = "</SnapShotDataSets>"+ sponsorStringList[sponsorStringList.size() - 1]
firstSponsor = false
}

StringWriter xmlOutput = new StringWriter()
XmlNodePrinter xmlNodePrinter = new XmlNodePrinter(new PrintWriter(xmlOutput))
xmlNodePrinter.print(snapshotNode)
String xmlStuff = xmlOutput.toString()
output.write(xmlStuff.getBytes())
}
output.write(endOfSponsor.getBytes())

}

output.write("</sponsors>".getBytes())
output.close()

println new Date()
println Runtime.getRuntime().totalMemory() - Runtime.getRuntime().freeMemory()

 

I did make some updates to attempt to get it to run.  For example, I removed the path in the scanner and replaced it with a dynamic process property that was assigned as 'current data' earlier in the process.  I also added the last bit of the generic scripting step because I've been told it was needed to run.  Below is that generic script i'm talking about.  I also changed the BufferedOutputStream output to be BufferedOutputStream output = new BufferedOutputStream(new FileOutputStream(OutDirectory)).  OutDirectory is another dynamic process property that is already created in the process and declared in the script.  Let me know if there is any additional information that would be helpful.

 

for( int i = 0; i < dataContext.getDataCount(); i++ ) {
InputStream is = dataContext.getStream(i);
Properties props = dataContext.getProperties(i);

dataContext.storeStream(is, props);
}

Outcomes