adding SOAP header in SOAP envelope using XSLT - xslt

i have an incoming SOAP message where there were no SOAP header tag present i need to add SOAP header in that. I am using this XSLT for doing this but SOAP HEADER is not getting added.
XSLT:
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:dp="http://www.datapower.com/extensions"
xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/"
extension-element-prefixes="dp"
exclude-result-prefixes="dp" >
<xsl:variable name="uuid" select="dp:variable('var://context/txn/uuid')" />
<xsl:template match="node()|#*">
<xsl:copy>
<xsl:apply-templates select="node()|#*"/>
</xsl:copy>
</xsl:template>
<xsl:template match="soapenv:Header">
<soapenv:Header>
<UUID><xsl:value-of select="$uuid"/></UUID>
</soapenv:Header>
</xsl:template>
</xsl:stylesheet>
The incomig SOAP mesagge can have header tag or it might not have header tag
Input SOAP Message Without Header tag:
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/">
<soapenv:Body>
<hmhs-medical-acknowledgement id="4080186649" result="FAIL""/>
</soapenv:Body>
</soapenv:Envelope>
Input SOAP Message With Header tag:
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/">
<soapenv:Header/>
<soapenv:Body>
<hmhs-medical-acknowledgement id="4080186649" result="FAIL""/>
</soapenv:Body>
</soapenv:Envelope>
Required Output SOAP Message:
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/">
<soapenv:Header>
<UUID>71A4B2FA029D412787B06E07685ED101</UUID>
</soapenv:Header>
<soapenv:Body>
<hmhs-medical-acknowledgement id="4080186649" result="FAIL""/>
</soapenv:Body>
</soapenv:Envelope>
Can somebody help how to add the SOAP header in that.

AFAICT, you want to do:
XSLT 1.0
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:dp="http://www.datapower.com/extensions"
xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/"
extension-element-prefixes="dp">
<xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes"/>
<xsl:strip-space elements="*"/>
<xsl:variable name="uuid" select="dp:variable('var://context/txn/uuid')" />
<!-- identity transform -->
<xsl:template match="#*|node()">
<xsl:copy>
<xsl:apply-templates select="#*|node()"/>
</xsl:copy>
</xsl:template>
<xsl:template match="/soapenv:Envelope">
<xsl:copy>
<soapenv:Header>
<UUID><xsl:value-of select="$uuid"/></UUID>
</soapenv:Header>
<xsl:apply-templates/>
</xsl:copy>
</xsl:template>
<xsl:template match="soapenv:Header"/>
</xsl:stylesheet>

Related

How to add SOAP Headers to soap message- XSLT

I'm getting the SOAP request with empty Headers. I want to add custom headers to the incoming request and copy the soap body as is to the response.How to add xml tags in the Headers ?
Below is the incoming request:
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/">
<soapenv:Header/>
<soapenv:Body>
<input>
<numb>15171</numb>
</input>
</soapenv:Body>
</soapenv:Envelope>
Expected Output:
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/">
<soapenv:Header>
<Username xmlns="http://blah.com">username</Username>
<Password xmlns="http://blah.com">password</Password>
</soapenv:Header>
<soapenv:Body>
<input>
<numb>15171</numb>
</input>
</soapenv:Body>
</soapenv:Envelope>
Here is my XSLT which I tried:
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:soapenv="http://soap/envelope/"
version="1.0">
<xsl:output omit-xml-declaration="yes" indent="yes"/>
<xsl:template match="#*|node()">
<xsl:copy>
<xsl:apply-templates select="#*|node()"/>
</xsl:copy>
</xsl:template>
<xsl:template match="soapenv:Header">
<xsl:copy>
<xsl:apply-templates select="#*|node()"/>
<soapenv:Header>
<Username xmlns="http://blah.com">username</Username>
<Password xmlns="http://blah.com">password</Password>
</soapenv:Header>
</xsl:copy>
</xsl:template>
<xsl:template match="soapenv:Header"/>
</xsl:stylesheet>
Here's how you could do it.
Note that your 'soapenv' namespace in your XSLT was not matching what is defined in your input XML.
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/"
version="1.0">
<xsl:output omit-xml-declaration="yes" indent="yes"/>
<xsl:template match="#*|node()">
<xsl:copy>
<xsl:apply-templates select="#*|node()"/>
</xsl:copy>
</xsl:template>
<xsl:template match="soapenv:Header">
<xsl:copy>
<Username xmlns="http://blah.com">username</Username>
<Password xmlns="http://blah.com">password</Password>
</xsl:copy>
</xsl:template>
</xsl:stylesheet>
See it working here: https://xsltfiddle.liberty-development.net/6q1SDkU

Input-Output transformation remove nodes and update nodes

How to translate the given input xml into the output as shown below.
The input xml should be transformed by removing the wsse:Security header completely and EventUser value must be updated with the Username node value.
I tried below xlst. It is not working
XLST -
<?xml version="1.0"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:template match="EventUser">
<xsl:copy>
<xsl:value-of select="Username"/>
</xsl:copy>
</xsl:template>
<xsl:template match="#*|node()">
<xsl:copy>
<xsl:apply-templates select="#*|node()"/>
</xsl:copy>
</xsl:template>
</xsl:stylesheet>
Input -
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/">
<soapenv:Header>
<wsse:Security mustUnderstandValue="1"
xmlns:wsse="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd">
<wsse:UsernameToken id="UsernameToken-274">
<wsse:Username>MyUsername</wsse:Username>
<wsse:Password Type="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-username-token-profile-1.0#PasswordText">Password</wsse:Password>
</wsse:UsernameToken>
</wsse:Security>
</soapenv:Header>
<soapenv:Body>
<axis2ns682:Create xmlns:axis2ns682="http://g22.test01.org/test02/RF">
<tns:CreateDetails xmlns:tns="http://g22.test01.org/test02/RF">
<tns:EventUser>Event</tns:EventUser>
<tns:PreApprovedTemplateID>221398</tns:PreApprovedTemplateID>
<tns:Priority>High</tns:Priority>
<tns:PlannedImplementation_Start>2017-09-29</tns:PlannedImplementation_Start>
</tns:CreateDetails>
</axis2ns682:Create>
</soapenv:Body>
</soapenv:Envelope>
Output -
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/">
<soapenv:Header>
</soapenv:Header>
<soapenv:Body>
<axis2ns682:Create xmlns:axis2ns682="http://g22.test01.org/test02/RF">
<tns:CreateDetails xmlns:tns="http://g22.test01.org/test02/RF">
<tns:EventUser>MyUsername</tns:EventUser>
<tns:PreApprovedTemplateID>221398</tns:PreApprovedTemplateID>
<tns:Priority>High</tns:Priority>
<tns:PlannedImplementation_Start>2017-09-29</tns:PlannedImplementation_Start>
</tns:CreateDetails>
</axis2ns682:Create>
</soapenv:Body>
</soapenv:Envelope>
You have three problems with your XSLT
You have not accounted for namespaces in your XSLT. In your XML, the elements are in various namespaces (the EventUser element is in namespace http://g22.test01.org/test02/RF as denoted by the tns: prefix.
You have not coded anything to remove the wsse:Security element
The template matching EventUser is selecting Username, which would only would if Username was a child of EventUser. You actually need to select it from the soap:Header
Try this XSLT
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/"
xmlns:tns="http://g22.test01.org/test02/RF"
xmlns:wsse="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd"
version="1.0">
<xsl:template match="wsse:Security" />
<xsl:template match="tns:EventUser">
<xsl:copy>
<xsl:value-of select="//soapenv:Header/wsse:Security/wsse:UsernameToken/wsse:Username"/>
</xsl:copy>
</xsl:template>
<xsl:template match="#*|node()">
<xsl:copy>
<xsl:apply-templates select="#*|node()"/>
</xsl:copy>
</xsl:template>
</xsl:stylesheet>

Modify the content inside the SOAP envolope body using XSLT

I have a scenario, where i have to only alter the value(serverURL) of one attribute inside the SOAP body and leave the rest intact.
I am not able to find a solution for it. please help.
XML file is
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/">
<soapenv:Body>
<loginResponse>
<result>
<metadata>xxx</metadata>
<passwordExpired>xx</passwordExpired>
<sandbox>xx</sandbox>
<serverUrl>xx</serverUrl>
<userId>xx</userId>
<userInfo>
<accessibilityMode>xx</accessibilityMode>
</userInfo>
</result>
</loginResponse>
</soapenv:Body>
</soapenv:Envelope>
XSLT File is
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" >
<xsl:output method="xml" indent="yes" omit-xml-declaration="yes"/>
<xsl:template match="*|#*|text()">
<xsl:copy>
<xsl:apply-templates select="*|#*|text()"/>
</xsl:copy>
</xsl:template>
<xsl:template match="serverUrl">
<serverUrl>https://Sahoo/Nrusingha</serverUrl>
</xsl:template>
</xsl:stylesheet>

XSLT transformation of soap

I have this xml file
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:tes="http://testwork/">
<soapenv:Header/>
<soapenv:Body>
<tes:sayHelloWorldFrom>
<!--Optional:-->
<arg0>?</arg0>
</tes:sayHelloWorldFrom>
</soapenv:Body>
</soapenv:Envelope>
I want to extract body using xslt transformation, my xsl is
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:soapenv="http://www.w3.org/2003/05/soap-envelope"
xmlns:m="http://www.example.org/stock">
<xsl:template match="/">
<xsl:apply-templates select="soapenv:Envelope/soapenv:Body/*"/>
</xsl:template>
<xsl:template match="#*|node()">
<xsl:copy>
<xsl:apply-templates select="#*|node()"/>
</xsl:copy>
</xsl:template>
</xsl:stylesheet>
But during the transformation there appears error
Unable to perform XSL transformation on your XML file. null
What is wrong with my xsl?
Your XSL is missing the namespaces that are in your XML. Without it, your XSL can't find your elements in the XML because it would be looking in the wrong namespace for it.
So add
xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/"
xmlns:tes="http://testwork/"
To your XSL and it should transform without issue.

Adding namespace to child elements using xslt

below is the input xml:
<ns:TXLife xmlns:ns="http://ACORD.org/Standards/Life/2">
<TXLifeResponse>
<TransRefGUID/>
<TransExeDate/>
<TransExeTime/>
<TransType tc="228"/>
</ns:TXLife>
and below is my XSLT :
xmlns:ns="http://ACORD.org/Standards/Life/2" version="1.0">
<xsl:output omit-xml-declaration="yes" indent="yes"/>
<xsl:template match="/">
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:acor="http://www.foresters.com/esb/ws/wsdl/ACORD-v1.0" xmlns:ns="http://ACORD.org/Standards/Life/2">
<soapenv:Header/>
<soapenv:Body>
<xsl:copy>
<xsl:apply-templates />
</xsl:copy>
</soapenv:Body>
</soapenv:Envelope>
</xsl:template>
<xsl:template match="node() [local-name(.) = 'TXLife']">
<xsl:element name="ns:{local-name()}">
<xsl:apply-templates select="#*|node()"/>
</xsl:element>
</xsl:template>
By using this tranformation i am not able to add namespace prefix to all the child element of TXLife.
how to add namespace prefix (ns) to all child elements? so that it should look as below
<ns:TXLifeResponse>
<ns:TransRefGUID/>
<ns:TransExeDate/>
<ns:TransExeTime/>
<ns:TransType tc="228"/>
</ns:TXLife>
If you want only TXLife and descendant to be under http://ACORD.org/Standards/Life/2 namespace, use this stylesheet:
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:ns="http://ACORD.org/Standards/Life/2"
xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/">
<xsl:template match="/">
<soapenv:Envelope>
<soapenv:Header/>
<soapenv:Body>
<xsl:apply-templates/>
</soapenv:Body>
</soapenv:Envelope>
</xsl:template>
<xsl:template match="*[ancestor-or-self::ns:TXLife]">
<xsl:element name="ns:{local-name()}">
<xsl:apply-templates select="#*|node()"/>
</xsl:element>
</xsl:template>
<xsl:template match="#*|node()">
<xsl:copy>
<xsl:apply-templates select="#*|node()"/>
</xsl:copy>
</xsl:template>
</xsl:stylesheet>
Output:
<soapenv:Envelope
xmlns:ns="http://ACORD.org/Standards/Life/2"
xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/">
<soapenv:Header />
<soapenv:Body>
<ns:TXLife>
<ns:TXLifeResponse>
<ns:TransRefGUID></ns:TransRefGUID>
<ns:TransExeDate></ns:TransExeDate>
<ns:TransExeTime></ns:TransExeTime>
<ns:TransType tc="228"></ns:TransType>
</ns:TXLifeResponse>
</ns:TXLife>
</soapenv:Body>
</soapenv:Envelope>
Your XML isn't valid, but I assume you just've missed the closing TXLifeResponse element.
The following transformation will do what you want:
XML:
<?xml version="1.0" encoding="UTF-8"?>
<ns:TXLife xmlns:ns="http://ACORD.org/Standards/Life/2">
<TXLifeResponse>
<TransRefGUID/>
<TransExeDate/>
<TransExeTime/>
<TransType tc="228"/>
</TXLifeResponse>
</ns:TXLife>
XSLT:
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet
xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0"
xmlns:ns="http://ACORD.org/Standards/Life/2">
<xsl:output omit-xml-declaration="yes" indent="yes"/>
<xsl:template match="/">
<soapenv:Envelope
xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/"
xmlns:acor="http://www.foresters.com/esb/ws/wsdl/ACORD-v1.0"
xmlns:ns="http://ACORD.org/Standards/Life/2">
<soapenv:Header/>
<soapenv:Body>
<xsl:copy>
<xsl:apply-templates/>
</xsl:copy>
</soapenv:Body>
</soapenv:Envelope>
</xsl:template>
<xsl:template match="*">
<xsl:element name="ns:{local-name()}">
<xsl:apply-templates select="#*|node()"/>
</xsl:element>
</xsl:template>
<xsl:template match="#*">
<xsl:copy-of select="."/>
</xsl:template>
</xsl:stylesheet>
Output:
<soapenv:Envelope
xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/"
xmlns:acor="http://www.foresters.com/esb/ws/wsdl/ACORD-v1.0"
xmlns:ns="http://ACORD.org/Standards/Life/2">
<soapenv:Header/>
<soapenv:Body>
<ns:TXLife>
<ns:TXLifeResponse>
<ns:TransRefGUID/>
<ns:TransExeDate/>
<ns:TransExeTime/>
<ns:TransType tc="228"/>
</ns:TXLifeResponse>
</ns:TXLife>
</soapenv:Body>
</soapenv:Envelope>
The template xsl:template match="node()[local-name(.) = 'TXLife']" is somewhat strange to me. What are you trying to accomplish? Maybe we can help explain why this isn't the appropriate way to do it.