Problem
It may be necessary to process XML strings and files in your automated tests. This article provides examples for common ways to use the Groovy programming language to process, parse, manipulate and output XML information.
Solution
Cycle includes steps to execute simple Groovy statements inline as well as execute more complex Groovy scripts.
The 2 Cycle steps that execute Groovy are:
I execute Groovy "<GROOVY_STATEMENTS>"
I execute Groovy script "<GROOVY_SCRIPT_FILE>"
This article assumes a conceptual familiarity with Groovy/Java including general syntax, data types, import statements, class references and method usage.
For more information on Groovy see Apache Groovy
Two items of note regarding Cycle and Groovy.
- 1. Cycle can only input and output String and Number data types with Groovy statements and scripts.
- Dates, arrays, lists, maps are not yet functional inputs or outputs but can be used within a Groovy script.
- 2. Cycle outputs a variable called $groovy_result which represents the final result
- Custom variables can be assigned and used
Examples
Replace value in first occurrence of an XML tag
This Groovy script, replaceFirst.groovy, imports the necessary Classes, parses an XML string value, uses the node attributes to find and replace the value in the first occurrence of a tag, and then prints the output in Notepad (just for visual validation) in 2 forms:
1) XML format
2) a single line string
The values passed in from Cycle are XML - the XML string, tag - the XML tag to search by, and val - the replacement value for the tag.
import java.util.*
import groovy.xml.*
//Parse the input string to XML
def stringXML = new XmlParser().parseText(xml)
//Use XML Node attributes to replace first occurrence
stringXML.depthFirst().find{it -> it.name() == tag}.value = val
//Output in XML Style
def stringWriter = new StringWriter()
new XmlNodePrinter(new PrintWriter(stringWriter)).print(stringXML)
def newXml = stringWriter.toString()
XmlFormat = newXml
//Output on a single line
StringBuilder fileContents = new StringBuilder((int)newXml.length())
Scanner scanner = new Scanner(newXml)
while(scanner.hasNextLine()) {
fileContents.append(scanner.nextLine())
}
singleLineFormat = fileContents.toString().replaceAll("\\s","")
This is an example of a Scenario calling replaceFirst.groovy. The expected output will be only the first occurrence of the tag WH_ID will have it's value replaced to WMD2.
Scenario: Replace value in first occurrence of a tag
Given I assign "<HDR><WH_ID>WMD1</WH_ID><CLIENT>CLT1</CLIENT><DTL><WH_ID>WMD1</WH_ID><ORDER>ORD1</ORDER><LINE>1</LINE><PART>WIDGET</PART></DTL></HDR>" to variable "xml"
And I assign "WH_ID" to variable "tag"
And I assign "WMD2"to variable "val"
When I execute groovy script "scripts\replaceFirst.groovy"
Then I execute process "notepad.exe"
And I wait 1 seconds
Then I enter "OUTPUT IN XML STYLE FORMAT:"
And I press keys ENTER
And I enter $XmlFormat
Then I enter "OUTPUT IN SINGLE LINE FORMAT:"
And I press keys ENTER
And I enter $singleLineFormat
Replace all occurrences of an XML tag
To go from replace the value in the first tag to replace all requires a small change in the Groovy script above.
The code below replaces the bold lines in the script above
//Use XML Node attributes to replace all occurrences
stringXML.depthFirst().findAll{it -> it.name() == tag}.each{it -> it.value = val}
Unless the values of the variables need to change, the Scenario itself does not require a change to validate the new logic.
Replace value in X occurrence of an XML tag
To go from replacing all to specifying which node's value to replace also just requires a small change to the original Groovy script.
The code below replaces the bold lines in the original Groovy script
//Use XML Node attributes to replace value by tag and node
stringXML.depthFirst().findAll{it -> it.name() == tag}[node-1].value = val
The Features simply requires the addition of setting a node variable:
And I assign 2 to variable "node"
Comments
0 comments
Article is closed for comments.