Parsing and Recursion of SOAP response in SoapUI - web-services

I have a SOAP response from a TestStep in SoapUI. I want to parse each value of a specific element in the response and send it as a parameter to a separate request call to another web service.
<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>
<searchResponse xmlns="urn:messages_2012_2.platform.webservices.technoplat.com">
<platformCore:searchResult xmlns:platformCore="urn:core_2012_2.platform.webservices.technoplat.com">
<platformCore:searchRowList>
<platformCore:searchRow xsi:type="tranSales:TransactionSearchRow" xmlns:tranSales="urn:sales_2012_2.transactions.webservices.technoplat.com">
<tranSales:basic xmlns:platformCommon="urn:common_2012_2.platform.webservices.technoplat.com">
<platformCommon:tranId>
<platformCore:searchValue>17678</platformCore:searchValue>
</platformCommon:tranId>
</tranSales:basic>
</platformCore:searchRow>
<platformCore:searchRow xsi:type="tranSales:TransactionSearchRow" xmlns:tranSales="urn:sales_2012_2.transactions.webservices.technoplat.com">
<tranSales:basic xmlns:platformCommon="urn:common_2012_2.platform.webservices.technoplat.com">
<platformCommon:tranId>
<platformCore:searchValue>17705</platformCore:searchValue>
</platformCommon:tranId>
</tranSales:basic>
</platformCore:searchRow>
<platformCore:searchRow xsi:type="tranSales:TransactionSearchRow" xmlns:tranSales="urn:sales_2012_2.transactions.webservices.technoplat.com">
<tranSales:basic xmlns:platformCommon="urn:common_2012_2.platform.webservices.technoplat.com">
<platformCommon:tranId>
<platformCore:searchValue>17777</platformCore:searchValue>
</platformCommon:tranId>
</tranSales:basic>
</platformCore:searchRow>
</platformCore:searchRowList>
</platformCore:searchResult>
</searchResponse>
</soapenv:Body>
In the SOAP response above, I want to capture the values: 17678, 17705 and 17777 separately and send them as a parameter to another SOAP Request TestStep. Most people recommend using a groovy script for the recursion.
My questions are:
1. whats the best way to perform extraction of values from the SOAP response above and iterate and make a separate SOAPRequest TestStep in SoapUI?
2. Assuming each value is extracted in a Groovy TestStep, how can I feed those out to a "results.txt" kind of csv (name value pair) file outside.
Any suggestions would be appreciated.

This is the way I used before may be not the best.
parsing XML by XmlSluper.
There are many ways to process XML (see: http://groovy.codehaus.org/Processing+XML)
use XmlParser and CSVWriter (opencsv) to convert XML to CSV
I'd seen good example from here: http://blog.ktronline.com/2011/12/creating-csv-file-from-xml-using-groovy.html

if you're using soapUI Pro the easiest way to do this is use the DataSource TestStep with a XML DataSource (see http://blog.smartbear.com/software-quality/bid/170520/How-to-Use-XML-DataSources-for-Response-Processing-in-soapUI for an example). If you're using the free version then scripting is your best option!
Good Luck!
/Ole

Related

BizTalk mapping: Getting a value from soapenv:Header

I'm trying to map a message from the following format via xslt:
<soapenv:Envelope xmlns:soapenv="..." ns...>
<soapenv:Header>
<ns:myHeader>
<ns1:myData>VALUE_I_WANT</ns1:myData>
</ns:myHeader>
</soapenv:Header>
<soapenv:Body>
<ns2:otherData>
...
</ns2:otherData>
</soapenv:Body>
</soapenv:Envelope>
Currently my mapping handles all of the fields in the soapenv:Body tag, but for one of my mapped nodes I need the value in soapenv:Header > ns:myHeader > ns1:myData.
Is it possible to get a value from the soap header in XSLT and what kind of xpath would I need to achieve this?
Assuming you use the WCF-BasicHttp adapter, you could use xslt like you wanted, but only if you specified Envelope -- entire <soap:Envelope> as data selection for the SOAP Body element. If you don't specify it, your header will be removed from the message body and xpath statements on the header will be impossible.
Your other option is getting the value from the context property InboundHeaders with namespace http://schemas.microsoft.com/BizTalk/2006/01/Adapters/WCF-properties. The adapter puts the SOAP header values into that InboundHeaders context property by default. If you need the context value in a mapping, without an orchestration, try looking into the community made Context Accessor Functoid.
Doing your own property promotion on header values, like you asked for in the comments, is also possible, but not in xslt. Only if you add an XML Disassembler Pipeline Component, then make a schema of the entire soap message, then set promotions on the schema and finally; specify the schema in the Document schemas part of the Pipeline Component. I wouldn't suggest using this approach, as it requires you to deploy a soap schema which will be duplicate with the default BizTalk soap schema.

Web service - SOAPui - Receiver Failed to serialize node AXIS2

Hy Guys,
I have a Web service problem. The used environment: SOAP - TOMCAT+AXIS2 - Gigaspace - Magic XPA 3.3
I have made 2 closely same external xpa program what gives back a blob in the Task's property sheet's Return value. It's "answer" back an XML, the simle different is that the first one make (XPA merge) a smaller (18KB) file (from a Filtered DB source), the bigger is write out the whole record aggregation. (1025KB)
When the soap UI receives the first one, everything is fine, i got the result XML on SOAP side. The bigger one shows this error:
With11Endpoint:
<soapenv:Fault>
<faultcode>soapenv:**Server**</faultcode>
<faultstring>**Failed to serialize node**</faultstring>
With12Endpoint:
<soapenv:Fault>
<soapenv:Code>
<soapenv:Value>soapenv:**Receiver**</soapenv:Value>
</soapenv:Code>
<soapenv:Reason>
<soapenv:Text xml:lang="en-US">**Failed to serialize node**</soapenv:Text>
</soapenv:Reason>
The only different is the size of files i think so. I have read some option to solve it like BasicHttpBinding's MaxReivedMessageSize and MaxBuffer size, but i could not find them to change values.
Does anyone have experience in this solutions?
Best Regards,
Gábor
For the future. The XML what has sent contained wrong values. Not tipical XML invalid character, instead an character. So i you have a SOAP error like that, try to Validate your XML file to search an option to solve your problem. ;)

In Camel, how to set a header value with result of XSL transform?

I am using camel to implement a proxy over a new backend that looks like an older interface. The older API has username/password credentials in the request body and the new backend service uses basic auth. I have an XSL that will extract the un/pw, do a simple lookup against an XML database (the credentials might not map exactly), and will return the correct credentials as a base64 encoded string. I cannot figure out how to set this as an http Authentication header value (e.g. how to process an XSL transform as an expression in .setHeader() call).
I have SOAP requests that look like this:
<soapenv:Envelope>
<soapenv:Body>
<XService>
<_Header username="demo" password="demo"/>
<_Body>
<_RequestParameters xsi:type="RequestServiceReport">
...
</_RequestParameters>
</_Body>
</XService>
</soapenv:Body>
and my route (using Java DSL) looks sort of like this:
from("jetty:http://161.228.88.168:8080/sap2rjm")
.choice()
.when().simple("${header.channel}")
...
.when().simple("${in.header.emx} == 'authenticate'")
...
.endChoice()
// If the request is for a report, route it to the new service
.when().xpath("//_RequestParameters[#type='RequestServiceReport']")
// TODO: How to get header from the body of the message and set as the header value?
// Stylesheet transform_credentials will extract username/password from body, transform
// for the new service (dev.reportjam) and will base4 encode to produce a string like this one...
.setHeader("Authorization", constant("Basic ZGVtbzpkZW1v"))
.to("xslt:transform_request.xsl")
.to("http://dev.reportjam.com/services/ReportMix?bridgeEndpoint=true")
.to("xslt:transform_response.xsl")
.removeHeaders("*")
.endChoice()
.otherwise()
...
.endChoice()
.end();
I do have another stylesheet that will process the soap request, extract the un/pw, apply some logic to transform it, and then base64 encode it but I do not know how to call this in the setHeader() call above.
Thanks
You can use xpath to grab something from an XML body and then store that as a header.
http://camel.apache.org/xpath
.setHeader("foo", xpath("/foo/bar"))
The trick is to write the xpath expression so it works. As your XML message uses namespaces you need to use them in the xpath expression also. See that link for more details.
Also you should enable stream caching as you will read the message body as part of this xpath expression evaluation.
See the top of this link about stream caching and jetty: http://camel.apache.org/jetty

This XML file does not appear to have any style information associated with it

I have deployed my webservice into Tomcat.
The WSDL has got some operations like ViewOptions, but when I ran that, I got this error:
This XML file does not appear to have any style information associated with it. The document tree is shown below.
<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/">
<soap:Body>
<soap:Fault>
<faultcode>soap:Server</faultcode>
<faultstring>1</faultstring>
</soap:Fault>
</soap:Body>
</soap:Envelope>
Why do we get this error?
The message isn't an "error" but rather a warning n need not be solved but ignored. An XML document is a data structure but does not contain any presentation/style information internally. Normally an XML document is used in inter-application communication or as a pure data structure that is then used with additional presentation/style information to display to users.
XML can be applied style by XSLT just as HTML by CSS and the above warning can be eradicated An eg: of applying xls to xml
We don't present xml using xls for RSS, Web Services as they are just used for communication without applying stylesheet rather than meant to be presented to user in browser.
So, everything is fine here.
what worked for my case. I replaced all the links of ... with window.open("...link", "_self") and changed
import {
HashRouter as Router,
} from 'react-router-dom';

Array of element in WSDL File

Hello I'm developping some web services in java, so I have created a wsdl file to describe this services.
With my wsdl I create the web services (servcer side). but I can't create the client side because
I think the problem is
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:bil="http://tempuri.org/Services/" xmlns:soapenc="http://schemas.xmlsoap.org/soap/encoding/">
<soapenv:Header/>
<soapenv:Body>
<bil:ArrayOfElement soapenc:arrayType="?" soapenc:offset="?" id="?" href="?">
<!--1 or more repetitions:-->
<Element>
<code>?</code>
<codeElement>?</codeElement>
<TypeService>?</TypeService>
</Element>
</bil:ArrayOfElement>
</soapenv:Body>
</soapenv:Envelope>
In fact, I don't know what we must put in this line:
<bil:ArrayOfElement soapenc:arrayType="?" soapenc:offset="?" id="?" href="?">
And for my tests I send this enveloppe and it works (but like you see it's another wsdl):
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:bil="http://tempuri.org/Services/">
<soapenv:Header/>
<soapenv:Body>
<bil:ArrayOfElement>
<Element>
<code>exmepleCode</code>
<codeElement>exmempleCodeElement</codeElement>
<TypeService>a_Service_Type</TypeService>
</Element>
</bil:ArrayOfElement>
<!-- other elements-->
</soapenv:Body>
</soapenv:Envelope>
How did you create the WSDL?
one important issue when working with web services, or xml schemas (xsd) in general, is that there's no simple one to one mapping between xsd and language specific types (java in this case).
one of the implication is when doing a 'round trip' mapping (java to xsd, and then xsd to java) you don't get always what you started with - especially when using non simple types such as arrays or other containers.
The solution in this case is to create a "correct" xsd schema, and derive the javadefinitions for the client and the server from this schema - only a single xsd to java transformation is done, so no issues of rount trip mapping are encountered.
To create such a xsd, you should use the native methods of defining collections in xsd, which is basically adding minOccurs and maxOccurs attributes to the basic element.
you can find more detailed reference here
Note that you don't have to use hand crafted xsd - you can also use any xsd editor (most modern IDE's have one) to get the same results.