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
Related
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>
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>
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>
I have some xml as follows...
<ns1:service1 xmlns:ns1="http://foo.com/service_1" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<ns1:SystemInfo>
<ns1:functionMode>Y</ns1:functionMode>
</ns1:SystemInfo>
</ns1:service>
Now I need to take it and do 2 things
Wrap in a SOAP envelope
insert a trans tag in SystemInfo
the following works for wrapping...
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output omit-xml-declaration="yes" indent="yes"/>
<xsl:param name = "transId" />
<xsl:template match="#*|node()">
<xsl:copy>
<xsl:apply-templates select="#*|node()"/>
</xsl:copy>
</xsl:template>
<xsl:template match="*">
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/">
<soapenv:Header/>
<soapenv:Body>
<xsl:copy-of select="/*"/>
</soapenv:Body>
</soapenv:Envelope>
</xsl:template>
</xsl:stylesheet>
Now I need to add the tag, problem is we do not know what the Namespace is (and it could change per request). So I can't hardcode it. However, it will already be in the root tag.
So after I would want...
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/">
<soapenv:Header/>
<soapenv:Body>
<ns1:service1 xmlns:ns1="http://foo.com/service_1" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<ns1:SystemInfo>
<ns1:trans />
<ns1:functionMode>Y</ns1:functionMode>
</ns1:SystemInfo>
</ns1:service>
</soapenv:Body>
</soapenv:Envelope>
But this doesn't seem to accomplish it....
<xsl:template match="*[local-name()='SystemInfo']">
<xsl:copy>
<xsl:element name="type"/>
<xsl:call-template name="copy-children"/>
</xsl:copy>
</xsl:template>
<!-- Copy the children of the current node. -->
<xsl:template name="copy-children">
<xsl:copy-of select="./*"/>
</xsl:template>
What should the above be instead?
Instead if using xsl:copy-of which will just copy the current element without allowing you to make any changes, use xsl:apply-templates
<soapenv:Body>
<xsl:apply-templates select="#*|node()"/>
</soapenv:Body>
Then you can write a template to match your SystemInfo element, and add whatever new elements you need. You could even make use of the namespace-uri function to add it with the same namespace.
<xsl:template match="*[local-name()='SystemInfo']">
<xsl:copy>
<xsl:element name="trans" namespace="{namespace-uri()}" />
<xsl:apply-templates select="#*|node()"/>
</xsl:copy>
</xsl:template>
Try this XSLT
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output omit-xml-declaration="yes" indent="yes"/>
<xsl:param name="transId"/>
<xsl:template match="#*|node()">
<xsl:copy>
<xsl:apply-templates select="#*|node()"/>
</xsl:copy>
</xsl:template>
<xsl:template match="/">
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/">
<soapenv:Header/>
<soapenv:Body>
<xsl:apply-templates select="#*|node()"/>
</soapenv:Body>
</soapenv:Envelope>
</xsl:template>
<xsl:template match="*[local-name()='SystemInfo']">
<xsl:copy>
<xsl:element name="trans" namespace="{namespace-uri()}" />
<xsl:apply-templates select="#*|node()"/>
</xsl:copy>
</xsl:template>
</xsl:stylesheet>
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.