BizTalk mapping: Getting a value from soapenv:Header - xslt

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.

Related

how to use lookups in xslt mediator in wso2esb

In WSO2ESB, using the xslt mediator, I want to transform a webservice result. I do that using an xslt file. In this file, I want to do some lookups, to transform some values into something else.
In Oracle, you can use a dvm for that.
In plain xslt, it looks like the document('somefile.xml') function could do the trick, but WSO2ESB looks for the xml file on the filesystem, and the resources property on the xslt mediator does not translate document() contents into correct paths.
Then, I tried inputting the XML by reading it into a property in ESB, and then pass the property to the mediator. This also does not work, because the content of the XML is then
passed as one string value instead of a nodeset.
Am I doing something wrong - what is the correct way of doing this?
you can inject the content of your document 'somefile.xml' as a subtree inside the current message before invoking XSLT mediator :
Define a local entry named 'somefile' with the content of 'somefile.xml'
Use enrich mediator to inject it's content inside current message :
<enrich>
<source clone="true" xpath="get-property('somefile')"/>
<target type="body" action="child"/>
</enrich>
In your XSL transformation, use this content rather than refering to $somefile/xxx...
(and forget this content in the result)
By default, the XSLT mediator acts on the message body, so shouldn't be necessary to use the document function to load the XML seperately. For an example of the xslt mediator, see this link to the current wso2esb documentation.
If you want to replace a few values in your XML, you may want to try the enrich mediator. The enrich mediator can use Xpath expressions to select the source and target expressions for replacement.

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

Parsing and Recursion of SOAP response in SoapUI

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

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.