问题
I am working on a groovy script in which I have to take values from request XML file and write those into XML response file.
I know how to read values from normal XML as given below:
def text = '''
<list>
<technology>
<name>Groovy</name>
</technology>
</list>
'''
def list = new XmlParser().parseText(text)
println list.technology.name.text()
I can easily access nodes using above syntax. But in my case the request file have 'keyword:label' syntax. Consider below mentioned request file for currency converter:
<soap:Envelope xmlns:soap="http://www.w3.org/2003/05/soap-envelope" xmlns:web="http://www.webserviceX.NET/">
<soap:Header/>
<soap:Body>
<web:ConversionRate>
<web:FromCurrency>USD</web:FromCurrency>
<web:ToCurrency>INR</web:ToCurrency>
</web:ConversionRate>
</soap:Body>
</soap:Envelope>
How to read value of FromCurrency
in this case? Instead of using XMLParser, is there any other efficient and good way to handle larger XML files?
Also, while writing values in the response I am writing by creating multiple variables in script and using their values in response using syntax "${var_name}.
If I want to write many values (suppose 20+) from request into response, then variable for individual writing is not good way. So is there any good and efficient way for this?
回答1:
You can get FromCurrency
like so (using XmlSlurper
):
def text = '''<soap:Envelope xmlns:soap="http://www.w3.org/2003/05/soap-envelope" xmlns:web="http://www.webserviceX.NET/">
<soap:Header/>
<soap:Body>
<web:ConversionRate>
<web:FromCurrency>USD</web:FromCurrency>
<web:ToCurrency>INR</web:ToCurrency>
</web:ConversionRate>
</soap:Body>
</soap:Envelope>'''
def list = new XmlSlurper().parseText(text)
println list.Body.ConversionRate.FromCurrency.text()
Not sure I understand the rest of your question
回答2:
With XmlParser
you have to explicitly use namespaces, within a string or declaring them:
import groovy.xml.*
def text = '''<soap:Envelope xmlns:soap="http://www.w3.org/2003/05/soap-envelope" xmlns:web="http://www.webserviceX.NET/">
<soap:Header/>
<soap:Body>
<web:ConversionRate>
<web:FromCurrency>USD</web:FromCurrency>
<web:ToCurrency>INR</web:ToCurrency>
</web:ConversionRate>
</soap:Body>
</soap:Envelope>'''
def s = new Namespace('http://www.w3.org/2003/05/soap-envelope', 'soap')
def w = new Namespace('http://www.webserviceX.NET/', 'web')
def parsed = new XmlParser().parseText(text)
assert 'USD' == parsed.'soap:Body'.'web:ConversionRate'.'web:FromCurrency'.text()
assert '' == parsed.Body.ConversionRate.FromCurrency.text()
assert 'USD' == parsed[s.Body][w.ConversionRate][w.FromCurrency].text()
Whereas with XmlSlurper
namespaces are ignored if not declared:
def slurped = new XmlSlurper().parseText(text)
assert 'USD' == slurped.Body.ConversionRate.FromCurrency.text()
assert '' == slurped.'soap:Body'.'web:ConversionRate'.'web:FromCurrency'.text()
slurped = new XmlSlurper().parseText(text).declareNamespace([soap: 'http://www.w3.org/2003/05/soap-envelope', web: 'http://www.webserviceX.NET/'])
assert 'USD' == slurped.Body.ConversionRate.FromCurrency.text()
assert 'USD' == slurped.'soap:Body'.'web:ConversionRate'.'web:FromCurrency'.text()
回答3:
To do so using XMLParser
instead of XmlSlurper
(by the way I prefer to use slurper):
def text = '''<soap:Envelope xmlns:soap="http://www.w3.org/2003/05/soap-envelope" xmlns:web="http://www.webserviceX.NET/">
<soap:Header/>
<soap:Body>
<web:ConversionRate>
<web:FromCurrency>USD</web:FromCurrency>
<web:ToCurrency>INR</web:ToCurrency>
</web:ConversionRate>
</soap:Body>
</soap:Envelope>'''
def list = new XmlParser().parseText(text)
log.info list.'soap:Body'.'web:ConversionRate'.'web:FromCurrency'.text() // prints Thu Oct 29 12:27:31 CET 2015:INFO:USD
Then instead to add multiple properties in the request and setting one by one in your script, if you want an alternative way you can construct your complete xml and set the request property of your testStep directly using the follow approach:
def text = '''<myNewRequest><someField1/><someField2/></myNewRequest>'''
def request = new XmlParser(true,true).parseText(text)
request.someField1[0].setValue('my new value')
request.someField2[0].setValue('another value')
// converts the xml to string
StringWriter sw = new StringWriter()
new XmlNodePrinter(new PrintWriter(sw)).print(request)
def modifiedRequest = sw.toString()
// get the testStep and set the request
context.testCase.getTestStepByName('SOAP Request').setPropertyValue('request',modifiedRequest)
Hope it helps,
来源:https://stackoverflow.com/questions/33411390/how-to-read-values-from-xml-request-and-write-into-xml-response-using-groovy