I am trying to read in a naked xml file and parse it but for some reason XMLSlurper doesn't seem to be able to see child nodes. To make things easy I have created a groovy script with the xml inside of it so you don't need to bother with importing a file etc. this part I can do without error.
Here is an example of what I am trying to do
def testxml = ''' <connStrings> <env> <envName>test</envName> <conn> <connName>wba</connName> <host>host01</host> <port>1500</port> <user>user01</user> <password>P@ssw0rd</password> <sid>sid01</sid> </conn> </env> </connStrings> ''' def myFile = new XmlSlurper().parseText(testxml) m = myFile.connStrings.env.envName.toString() log.info m c = myFile.count("//connStrings/env/envName/conn/connName") log.info c
When I run this it returns
Any help anyone can give would be greatly appreciated.
Solved! Go to Solution.
Sorry about it, that was actually done quickly (could not test) for the change that you requested ( to loop thru all environments, and connection names)
That was happening because, you provided all connection names, but some of them are not present in all environments.
Handled now, please take the updated script from github.
Here is the script:
def testxml = '''<connStrings> <env> <envName>test</envName> <conn> <connName>wba</connName> <host>host01</host> <port>1500</port> <user>user01</user> <password>P@ssw0rd</password> <sid>sid01</sid> </conn> </env> </connStrings>''' def connStrings = new XmlSlurper().parseText(testxml) println "Environment name : ${connStrings.env.envName}" println "Connection name : ${connStrings.env.conn.connName}"
Thank you for that. I also need to be able to count the <connName> node, in my actual file I have several of these. Do you know how that can be done?
I sort of can. Here is a mock up of the entire file. It has db connections for my job so I can't post the actual connection string info but the file is in this exact structure I just changed the values to generic values.
I thought this would be easier so I apologize for not saying exactly what I am trying to do. In order to be less confusing let me explain what I ultimately want to accomplish.
I have a soapui project that reads in the file and I want to add a groovy script that determines the current active environment (I have 2 test and sandbox) and then runs some logic that says if the active environment = "test" then grab all connection values under the <envname> of "test" and then set them to a property using the <connname> + <host> or <port> etc.
Then I have jdbc test steps that I configure to connect using the values I want out of the properties test step. I am already kind of doing this but my groovy script keeps getting larger every time I have to add a new connection so what I want to be able to do is to just grab all connections out of the external file that fall under a specific <envname> but I keep having trouble counting the child nodes.
I hope this makes sense if needed I could mock up a soapui project of what I am currently doing.
Thanks Rao
There can be multiple approaches, and here is the groovy script with one of the way to do so:
/**This script reads the connections file and retrieves the data
* as requested by the user
**/
//Read connections xml file, change path as per your environment def xml = new File('/tmp/connections.xml').text //Provide the environment, and connection name below //You can use different values for env and connName for different connections def env = 'test' def connName = 'wba' def connStrings = new XmlSlurper().parseText(xml) //Call the below defined methods def testConnectionDetails = getConnectionDetails(connStrings, env, connName) showConnectionDetails(testConnectionDetails, env, connName)
//Generate the connection string
def connStr = getConnectionString(testConnectionDetails) log.info "Connection String is : ${connStr}" /** * this method will return the connection for the details provided **/ def getConnectionDetails(def connectionStrings, String environmentName, String connectionName) { def envronment = connectionStrings.'**'.find{it.@name == environmentName} envronment.'**'.find{ it.name() == 'connName' && it == connectionName}.parent() } /** * this method will show the details provided in the connection **/ def showConnectionDetails(def connexionDetails, String environmentName, String connectionName){ log.info "Environment : ${environmentName}, Connection name : ${connectionName}" log.info "Details followed: " log.info "Host : ${connexionDetails.host}" log.info "Port : ${connexionDetails.port}" log.info "User : ${connexionDetails.user}" log.info "Password: ${connexionDetails.password}" log.info "Sid : ${connexionDetails.sid}"
}
/**
* This creates connection string and there is optional parameter prefix(which is for oracle)
* Change value for prefix otherwise
* Output format is :jdbc:oracle:thin:scott/tiger@myhost:1521:orcl
**/
def getConnectionString(def connexionDetails, def prefix='jdbc:oracle:thin:') {
"${prefix}${connexionDetails.user}/${connexionDetails.password}@${connexionDetails.host}:${connexionDetails.port}:${connexionDetails.sid}" as String
}
Not sure if you still need the conn count. Hope it may not needed anymore.
Hi Rao,
I get an error when trying the script you provided
def env = ['test', 'sandbox'] def connName = ['wba', 'vb', 'cnx', 'rb', 'subinfo'] def xml = '''<connStrings><env name="test"><conn><connName>wba</connName><host>host01</host><port>1500</port><user>wbauser</user><password>wbapassword</password><sid>test</sid></conn><conn><connName>vb</connName><host>host02</host><port>1500</port><user>vbuser</user><password>vbpassword</password><sid>test</sid></conn><conn><connName>cnx</connName><host>host03</host><port>1500</port><user>cnxuser</user><password>cnxpassword</password><sid>test</sid></conn><conn><connName>rb</connName><host>host04</host><port>1500</port><user>rbuser</user><password>rbpassword</password><sid>test</sid></conn></env><env name="sandbox"><conn><connName>wba</connName><host>host01</host><port>1500</port><user>wbauser</user><password>wbapassword</password><sid>sandbox</sid></conn><conn><connName>vb</connName><host>host02</host><port>1500</port><user>vbuser</user><password>vbpassword</password><sid>sandbox</sid></conn><conn><connName>cnx</connName><host>host03</host><port>1500</port><user>cnxuser</user><password>cnxpassword</password><sid>sandbox</sid></conn><conn><connName>subinfo</connName><host>host03</host><port>1500</port><user>subinfouser</user><password>subinfopassword</password><sid>sandbox</sid></conn></env></connStrings>''' def connStrings = new XmlSlurper().parseText(xml) //Get details of test environment def testConnectionDetails = getConnectionDetails(connStrings, env[0], connName) showConnectionDetails(testConnectionDetails, env[0], connName) //Get details of sandbox environment def sandboxConnectionDetails = getConnectionDetails(connStrings, env [1], connName) showConnectionDetails(sandboxConnectionDetails, env[1], connName)
And the error is
groovy.lang.MissingMethodException: No signature of method: Script8.getConnectionDetails(is applicable for argument types: (groovy.util.slurpersupport.NodeChild, java.lang.String, java.util.ArrayList) values: [wbahost011500wbauserwbapasswordtestvbhost021500vbuservbpasswordtestcnxhost031500cnxusercnxpasswordtestrbhost041500rbuserrbpasswordtestwbahost011500wbauserwbapasswordsandboxvbhost021500vbuservbpasswordsandboxcnxhost031500cnxusercnxpasswordsandboxsubinfohost031500subinfousersubinfopasswordsandbox, ...] error at line: 6
Also, what I really want to accomplish is that if I ever have to add a new connection the Groovy script does not need to be changed and all I would have to edit is the XML file. I have attached the script that I am currently using so you can see what I have so far.
Subject | Author | Latest Post |
---|---|---|