This is the response I am getting from soapui.
<PageList>
<offset>0</offset>
<totalLength>2</totalLength>
<result>
<Id>9</Id>
<Name>Cake</Name>
<Price>80</Price>
<quantity>1</quantity>
</result>
<result>
<Id>13</Id>
<Name>Tea</Name>
<Price>10</Price>
<quantity>5</quantity>
</result>
<result>
<Id>15</Id>
<Name>Cofee</Name>
<Price>15</Price>
<quantity>10</quantity>
</result>
</PageList>
How to display the name field separately like
Cake,Tea,Cofee
using groovy script
You can get the list of names in the following way:
def xml = '''<PageList>
<offset>0</offset>
<totalLength>2</totalLength>
<result>
<Id>9</Id>
<Name>Cake</Name>
<Price>80</Price>
<quantity>1</quantity>
</result>
<result>
<Id>13</Id>
<Name>Tea</Name>
<Price>10</Price>
<quantity>5</quantity>
</result>
<result>
<Id>15</Id>
<Name>Cofee</Name>
<Price>15</Price>
<quantity>10</quantity>
</result>
</PageList>'''
def slurped = new XmlSlurper().parseText(xml)
def names = slurped.result.Name.collect { it.text() }
println names
Related
I have zeep pulling soap data from a SOAP endpoint as:
'''<?xml version="1.0" encoding="utf-8"?>
<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<soap:Body>
<GetLogCategoriesResponse xmlns="http://mynamespace.net/client">
<GetLogCategoriesResult>
<IsSuccessful>true</IsSuccessful>
<Messages />
<Categories>
<LogCategory>
<Category>Client Call</Category>
<CategoryId>805</CategoryId>
<CategoryType>UDF</CategoryType>
</LogCategory>
<LogCategory>
<Category>Client Portal</Category>
<CategoryId>808</CategoryId>
<CategoryType>UDF</CategoryType>
</LogCategory>
<LogCategory>
<Category>Complaint Notes</Category>
<CategoryId>1255</CategoryId>
<CategoryType>UDF</CategoryType>
</LogCategory>
</Categories>
</GetLogCategoriesResult>
</GetLogCategoriesResponse>
</soap:Body>
</soap:Envelope>'''
I've tried pulling the data using Elementtree as below without success:
'''from zeep import Client, Transport
import xml.etree.ElementTree as ET
client = Client('http://sandbox.mynamespace.net/Client.asmx?wsdl')
with client.settings(raw_response=True):
soap_result = client.service.GetLogCategories(userName='user', password='pass')
namespaces = {
'soap': 'http://schemas.xmlsoap.org/soap/envelope/',
'a': 'http://mynamespace.net/client',
}
dom = ET.fromstring(soap_result.content)
print(dom)
names = dom.findall(
'./soap:Body'
'./a:GetLogCategoriesResponse'
'./a:GetLogCategoriesResult'
'./a:Categories'
'./a:LogCategory'
'./a:Category',
namespaces,)
print(names)
for name in names:
print('in For')
print(name.text)'''
I do have a partially working but it only pulls back the first instance of the data group, I need to pull back all groups:
'''from zeep import Client, Transport
from bs4 import BeautifulSoup
client = Client('http://sandbox.mynamespace.net/2.18/Client.asmx?wsdl')
with client.settings(raw_response=True):
soap_result = client.service.GetLogCategories(userName='uname', password='pass')
soup = BeautifulSoup(soap_result.text, 'html.parser')
searchTerms = ['Category','CategoryId','CategoryType']
for st in searchTerms:
print(st+'\t',)
print(soup.find(st.lower()).contents[0])'''
I am looking for any pointers or solutions that will work at this point.
Thanks again
Try this.
from simplified_scrapy.simplified_doc import SimplifiedDoc
html = '''<?xml version="1.0" encoding="utf-8"?>
<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<soap:Body>
<GetLogCategoriesResponse xmlns="http://mynamespace.net/client">
<GetLogCategoriesResult>
<IsSuccessful>true</IsSuccessful>
<Messages />
<Categories>
<LogCategory>
<Category>Client Call</Category>
<CategoryId>805</CategoryId>
<CategoryType>UDF</CategoryType>
</LogCategory>
<LogCategory>
<Category>Client Portal</Category>
<CategoryId>808</CategoryId>
<CategoryType>UDF</CategoryType>
</LogCategory>
<LogCategory>
<Category>Complaint Notes</Category>
<CategoryId>1255</CategoryId>
<CategoryType>UDF</CategoryType>
</LogCategory>
</Categories>
</GetLogCategoriesResult>
</GetLogCategoriesResponse>
</soap:Body>
</soap:Envelope>'''
doc = SimplifiedDoc(html)
Categories = doc.getElementsByTag('LogCategory')
print ([(c.Category.text,c.CategoryId.text,c.CategoryType.text) for c in Categories])
Result:
[('Client Call', '805', 'UDF'), ('Client Portal', '808', 'UDF'), ('Complaint Notes', '1255', 'UDF')]
Here are more examples of SimplifiedDoc here
I have response like this .
<S:Envelope xmlns:S="http://schemas.xmlsoap.org/soap/envelope/">
<S:Body>
<ns3:ResponseElement xmlns:ns2="http://www.example.com/services/common/example/xsd" xmlns:ns3="http://www.example.com/example/xsd">
<Info>
<Data>
<Site>OneValue</Site>
</Data>
<OtherData>
<Code>56789</Code>
<Time>2017-07-30</Time>
<SecondCode>ThirdValue</SecondCode>
<Number>111</Number>
</OtherData>
</Info>
</ns3:ResponseElement>
</S:Body>
</S:Envelope>
In groovy, how can I extract the response as XML inside the <S:Body> tag?
I figured the Answer. It may help other if looking for this
def body = context.expand('${TestStepName#Response#//soap:Body}')
log.info body
I try to select value of node from soap message (with gt and lt symbols) , but cant do that, i can only get body (root.Body) and other nodes are not visible, it is empty result. What i'm making wrong?
Thanks!
import groovy.util.slurpersupport.Node
import groovy.util.slurpersupport.NodeChild
import groovy.xml.XmlUtil
String source=
'''<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<soapenv:Body>
<ns0:GetListBy_QualificationResponse xmlns:ns0="urn:WS_CTM_People_ICEVA">
<ns0:getListValues>
<ns0:Person_ID>PPL000000301739</ns0:Person_ID>
<ns0:Submitter>soehler</ns0:Submitter>
<ns0:Profile_Status>Enabled</ns0:Profile_Status>
<ns0:Locale2>en_US</ns0:Locale2>
<ns0:VIP>No</ns0:VIP>
<ns0:Client_Sensitivity>Standard</ns0:Client_Sensitivity>
</ns0:getListValues>
</ns0:GetListBy_QualificationResponse>
</soapenv:Body>
</soapenv:Envelope>'''
def root = new XmlSlurper().parseText(source)
def Submitter =root.Body.GetListBy_QualificationResponse.getListValues.'*'.find { node->
node.name() == 'Submitter'
}
It is because the xml is escaped. In order to be able to retrieve the data property, it is required to unescape the xml string and pass it XmlSlurper.
Here is how it can be done:
String source='''<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<soapenv:Body>
<ns0:GetListBy_QualificationResponse xmlns:ns0="urn:WS_CTM_People_ICEVA">
<ns0:getListValues>
<ns0:Person_ID>PPL000000301739</ns0:Person_ID>
<ns0:Submitter>soehler</ns0:Submitter>
<ns0:Profile_Status>Enabled</ns0:Profile_Status>
<ns0:Locale2>en_US</ns0:Locale2>
<ns0:VIP>No</ns0:VIP>
<ns0:Client_Sensitivity>Standard</ns0:Client_Sensitivity>
</ns0:getListValues>
</ns0:GetListBy_QualificationResponse>
</soapenv:Body>
</soapenv:Envelope>'''
//map the unescape characters
def map = ['<' : '<', '>' : '>', '"' : '"', ''':'\'', '&':'&']
//Replace them in source string
map.collect {k,v -> source = source.replaceAll(k,v)}
//Now parse it
def root = new XmlSlurper().parseText(source)
//Get the submitter
def submitter = root.'**'.find { it.name() == 'Submitter' }
println submitter
You can quickly try online Demo
How do I read the nodename from a given XML response? I was using xmlSlurper in readyAPI Groovy editor but not able to get the values
I wanted to fetch the ROOM,GENR values from rom1:RoomType Code from xml response.
def RoomTypes = new XmlSlurper().parseText(responseTestSuite1)
Sample XML as below
<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/">
<soap:Header/>
<soap:Body>
<rom1:GetRoomTypesListResponse xsi:schemaLocation="xsdlocation" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:rom1="service">
<rom1:Success/>
<rom1:Hotels>
<rom1:Hotel HCode="ABSCD"/>
</rom1:Hotels>
<rom1:RoomTypes>
<rom1:RoomType Code="ROOM">
<rom1:Name Language="en">Guest room, King or Queen or Double</rom1:Name>
</rom1:RoomType>
<rom1:RoomType Code="GENR">
<rom1:Name Language="en">Guest room, 1 King</rom1:Name>
</rom1:RoomType>
</rom1:RoomTypes>
</rom1:GetRoomTypesListResponse>
</soap:Body>
</soap:Envelope>
Here is what you need :
//Pass xml string in to below parseText method
println new XmlSlurper().parseText(xml).'**'.findAll { it.name() == 'RoomType'}*.#Code
Output
You get the list of values i.e., ROOM, GENR as output
You can quickly try this online Demo
If you are using ReadyAPI / SoapUI, use following Script Assertion instead of separate groovy script test step
//check if response is ok
assert context.response,'Resonse is empty'
def pXml = new XmlSlurper().parseText(context.response)
def codes = pXml.'**'.findAll { it.name() == 'RoomType' }*.#Code
log.info codes
When using XmlParser, it automatically strips out unused namespace definitions. It doesn't appear to detect a namespace being used in a value.
Example Code: The value for attribute "type" is "xs:string" which requires the namespace definition, but XmlParser strips it out
import groovy.xml.XmlUtil
def xml = '''<?xml version="1.0" encoding="UTF-8"?>
<value xmlns:xs="http://xs" type="xs:string">http://localhost:8001/MyService</value>
'''
def doc = new XmlParser().parseText(xml)
println(xml)
println(XmlUtil.serialize(doc))
Output:
****ORIGINAL****
<?xml version="1.0" encoding="UTF-8"?>
<value xmlns:xs="http://xs" type="xs:string">http://localhost:8001/MyService</value>
****XML PARSED/SERIALIZED*****
<?xml version="1.0" encoding="UTF-8"?>
<value type="xs:string">http://localhost:8001/MyService</value>
Is there any way to tell XmlParser to keep this namespace definition??
def parser = new XmlParser()
parser.setFeature("http://xml.org/sax/features/namespaces", false)
parser.setFeature("http://xml.org/sax/features/namespace-prefixes", true)
doc = parser.parseText(xml)
println(XmlUtil.serialize(doc))