Adding soap envelope or remain same using XSLT 1.0 - xslt

My requirement is to add the soap wrapper for the request which is doesn't include soap and If the request does have the soap wrapper don't do anything.
Case 1: ADD the soap wrapper for plain XML request.
Case 2: Send the payload as it in case its already SOAP.
Code:
<?xml version="1.0" encoding="UTF-8"?>
<!-- This stylesheet adds one or removes a SOAP envelope if one is found -->
<xsl:stylesheet version="1.0" xmlns:dp="http://www.datapower.com/extensions" extension-element-prefixes="dp" exclude-result-prefixes="dp" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:tns="http://www.w3.org/1999/xhtml">
<xsl:output method="xml"/>
<xsl:template match="/">
<xsl:choose>
<xsl:when test="contains(.,'Envelope') = 'true' ">
<xsl:copy-of select="/"/>
</xsl:when>
<xsl:otherwise>
<soap:Envelope xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/" xmlns:wsse="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd" soap:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/">
<soap:Header/>
<soap:Body>
<xsl:copy-of select="/"/>
</soap:Body>
</soap:Envelope>
</xsl:otherwise>
</xsl:choose>
</xsl:template>
</xsl:stylesheet>
Sample request working one:
<ProductMovementReport xmlns="urn:cidx:names:specification:ces:schema:all:5:0" Version="5.0">
<Header>
<ThisDocumentIdentifier>
<DocumentIdentifier>1044911</DocumentIdentifier>
</ThisDocumentIdentifier>
</Header>
<ProductMovementReportBody>
<ProductMovementReportDetails>
<ReportingEntity>
<PartnerInformation>
<PartnerName>CHS</PartnerName>
<PartnerIdentifier Agency="GLN">123456</PartnerIdentifier>
</PartnerInformation>
</ReportingEntity>
</ProductMovementReportDetails>
</ProductMovementReportBody>
</ProductMovementReport>
This converts into SOAP message successfully
Sample_request_WithSOAPwrapper
Request:
<soap:Envelope xmlns:tns="http://www.w3.org/1999/xhtml" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/" xmlns:wsse="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd" soap:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/">
<soap:Header/>
<soap:Body>
<ProductMovementReport xmlns="urn:cidx:names:specification:ces:schema:all:5:0" Version="5.0">
<Header>
<ThisDocumentIdentifier>
<DocumentIdentifier>1044911</DocumentIdentifier>
</ThisDocumentIdentifier>
</Header>
<ProductMovementReportBody>
<ProductMovementReportDetails>
<ReportingEntity>
<PartnerInformation>
<PartnerName>CHS</PartnerName>
<PartnerIdentifier Agency="GLN">123456</PartnerIdentifier>
</PartnerInformation>
</ReportingEntity>
</ProductMovementReportDetails>
</ProductMovementReportBody>
</ProductMovementReport>
</soap:Body>
</soap:Envelope>
Gives output:
<?xml version="1.0" encoding="UTF-8"?>
<soap:Envelope xmlns:tns="http://www.w3.org/1999/xhtml" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/" xmlns:wsse="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd" soap:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/">
<soap:Header/>
<soap:Body>
<soap:Envelope soap:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/">
<soap:Header/>
<soap:Body>
<ProductMovementReport xmlns="urn:cidx:names:specification:ces:schema:all:5:0" Version="5.0">
<Header>
<ThisDocumentIdentifier>
<DocumentIdentifier>1044911</DocumentIdentifier>
</ThisDocumentIdentifier>
</Header>
<ProductMovementReportBody>
<ProductMovementReportDetails>
<ReportingEntity>
<PartnerInformation>
<PartnerName>CHS</PartnerName>
<PartnerIdentifier Agency="GLN">123456</PartnerIdentifier>
</PartnerInformation>
</ReportingEntity>
</ProductMovementReportDetails>
</ProductMovementReportBody>
</ProductMovementReport>
</soap:Body>
</soap:Envelope>
</soap:Body>
</soap:Envelope>
Update: I didn't add what's the problem I am facing.
The problem is extra soap wrapper is being added.
<soap:Envelope xmlns:tns="http://www.w3.org/1999/xhtml" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/" xmlns:wsse="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd" soap:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/">
<soap:Header/>
<soap:Body>
<soap:Envelope soap:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/">
<soap:Header/>
<soap:Body>
</soap:Body>
</soap:Envelope>
</soap:Body>
</soap:Envelope>
Can anyone please advise where I am doing it wrong?
My guess is I am doing the test condition wrong.

Let me suggest a different approach to the problem: First, remove any existing soap wrappers. Then add the necessary soap wrappers unconditionally.
XSLT 1.0
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/" >
<xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes"/>
<xsl:strip-space elements="*"/>
<!-- identity transform -->
<xsl:template match="#*|node()">
<xsl:copy>
<xsl:apply-templates select="#*|node()"/>
</xsl:copy>
</xsl:template>
<xsl:template match="/">
<soap:Envelope xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:wsse="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd" soap:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/">
<soap:Header/>
<soap:Body>
<xsl:apply-templates/>
</soap:Body>
</soap:Envelope>
</xsl:template>
<xsl:template match="soap:*">
<xsl:apply-templates/>
</xsl:template>
</xsl:stylesheet>

Related

How to remove wsu:id and namespace declaration by xslt 1.0

I would like to remove the attribute Id and the namespace in the tag soap:Body by using XSLT.
My sample soap response to transform is:
<soap:Envelope xmlns:soap="http://www.w3.org/2003/05/soap-envelope">
<soap:Header/>
<soap:Body wsu:Id="Body-a3aedbad-1ef4-44a9-9982-bfa5cf9fe25f" xmlns:wsu="http://docs.oasis-
open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd">
<soap:Fault>  
</soap:Fault>
</soap:Body>
</soap:Envelope>
My already implemented xslt is:
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/"
xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd"
exclude-result-prefixes="wsu">
<xsl:output method="xml" omit-xml-declaration="yes"
indent="yes" />
<!-- remove attribute Id with prefix wsu -->
<xsl:template match="#wsu:Id" />
<!-- removed unused namespace declarations in soap:Body, especially xlmns:wsu -->
<xsl:template match="*[local-name()='Body']">
<xsl:element name="{name()}">
<xsl:apply-templates select="#* | node()" />
</xsl:element>
</xsl:template>
<!-- copy all other elements -->
<xsl:template match="#*|node()">
<xsl:copy>
<xsl:apply-templates select="#*|node()" />
</xsl:copy>
</xsl:template>
</xsl:stylesheet>
The output: is
<soap:Envelope xmlns:soap="http://www.w3.org/2003/05/soap-envelope">
<soap:Header/>
<soap:Body>
<soap:Fault xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd">  
</soap:Fault>
</soap:Body>
</soap:Envelope>
The ouput should be
<soap:Envelope xmlns:soap="http://www.w3.org/2003/05/soap-envelope">
<soap:Header/>
<soap:Body>
<soap:Fault>  
</soap:Fault>
</soap:Body>
</soap:Envelope>
The attribute and the namespace is removed. The problem is that the namespace declaration is inherited to the child objects. Can anyone tell me a solution for my problem?
The second template, instead of matching <xsl:template match="*[local-name()='Body']">, needs to match <xsl:template match="soap:Body | soap:Body//*">. In addition, the namespaces in the XSLT, for reason I don't understand, differ from the ones in the XML, so you need to adapt the namespace declarations in the XSLT to say
xmlns:soap="http://www.w3.org/2003/05/soap-envelope"
xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd"
(this assumes the line break in the wsu namespace in the posted sample is a formatting error).

XSL transformation to add namespace and header (input & output described)

Beginner to XSL transformation, looking for help to convert the data using xsl.
Input data is as below:
<?xml version="1.0" encoding="UTF-8"?>
<soap:Envelope xmlns:soap="http://www.w3.org/2003/05/soap-envelope">
<soap:Body>
<abcRequest xmlns="http://google.com/2018/abcService">
<messageHeader>
<Id>000000</Id>
<aId>572b0285-7e06-4834-90c0-dc45eeeafe70</aId>
<version>1.0</version>
</messageHeader>
</abcRequest>
</soap:Body>
</soap:Envelope>
Expected output data is as below:
<soap:Envelope xmlns:soap="http://www.w3.org/2003/05/soap-envelope" xmlns:p="http://www.bnppf.com/20190101/TA/TA99eWLNotificationDataSrv">
<soap:Header>
<wsa:Action xmlns:wsa="http://www.w3.org/2005/08/addressing">http://www.gmail.com/20190101/newService</wsa:Action>
</soap:Header>
<soap:Body>
<p:abcRequest xmlns="http://google.com/2018/abcService">
<p:messageHeader>
<p:Id>000000</p:Id>
<p:aId>572b0285-7e06-4834-90c0-dc45eeeafe70</p:aId>
<p:version>1.0</p:version>
</p:messageHeader>
</p:abcRequest>
</soap:Body>
</soap:Envelope>
You can achieve the transformation with the following stylesheet:
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0" xmlns:soap="http://www.w3.org/2003/05/soap-envelope" xmlns:abc="http://google.com/2018/abcService" xmlns:p="http://www.bnppf.com/20190101/TA/TA99eWLNotificationDataSrv">
<xsl:output method="xml"/>
<xsl:template match="node()|#*">
<xsl:copy>
<xsl:apply-templates select="node()|#*" />
</xsl:copy>
</xsl:template>
<xsl:template match="soap:Envelope">
<soap:Envelope>
<soap:Header>
<wsa:Action xmlns:wsa="http://www.w3.org/2005/08/addressing">http://www.gmail.com/20190101/newService</wsa:Action>
</soap:Header>
<xsl:apply-templates select="soap:Body" />
</soap:Envelope>
</xsl:template>
<xsl:template match="abc:*">
<xsl:element name="p:{local-name()}">
<xsl:apply-templates select="node()|#*" />
</xsl:element>
</xsl:template>
</xsl:stylesheet>
But the following default xmlns namespace on your p:abcRequest element will not be created because it is superfluous.
<p:abcRequest xmlns="http://google.com/2018/abcService">
Instead, the xmlns:p namespace will be set for this element and its children.
The output is:
<?xml version="1.0" encoding="UTF-8"?>
<soap:Envelope xmlns:soap="http://www.w3.org/2003/05/soap-envelope" xmlns:abc="http://google.com/2018/abcService" xmlns:p="http://www.bnppf.com/20190101/TA/TA99eWLNotificationDataSrv">
<soap:Header>
<wsa:Action xmlns:wsa="http://www.w3.org/2005/08/addressing">http://www.gmail.com/20190101/newService</wsa:Action>
</soap:Header>
<soap:Body>
<p:abcRequest>
<p:messageHeader>
<p:Id>000000</p:Id>
<p:aId>572b0285-7e06-4834-90c0-dc45eeeafe70</p:aId>
<p:version>1.0</p:version>
</p:messageHeader>
</p:abcRequest>
</soap:Body>
</soap:Envelope>

adding SOAP header in SOAP envelope using 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>

how to select value wierd soap - xml

i'm new to xsl and i want to know how i can select value of the field r1
this is my xml (not a 100% soap)
<Result>
<send>
<x>1</x>
</send>
<received>
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/">
<soapenv:Body>
<ns1:Consult xmlns:ns1="http://www.example.org/New/">
<message>
<r1>2</r1>
</message>
</ns1:Consult>
</soapenv:Body>
</soapenv:Envelope>
</received>
</Result>
and i tried this
<xsl:value-of select="/Result/received/soap:Envelope/soap:Body[1]/*[namespace-uri()='http://www.example.org/New/' and local-name()='Consult'][1]/message/r1"/>
but it doesn't work
You need to register the SOAP namespace:
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/">
<xsl:template match="/">
<xsl:value-of
select="/Result/received/soap:Envelope/soap:Body[1]/*[
namespace-uri()='http://www.example.org/New/'
and local-name()='Consult'][1]/message/r1" />
</xsl:template>
</xsl:stylesheet>
Better yet, register them both:
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/"
xmlns:ns1="http://www.example.org/New/>
<xsl:template match="/">
<xsl:value-of
select="/Result/received/soap:Envelope/
soap:Body[1]/ns1:Consult[1]/message/r1" />
</xsl:template>
</xsl:stylesheet>

XSLT to get the XML from the body of a SOAP message

I am trying to figure out how to grab everything, including the XML tags, from the body of a soap message.
Here is what I have so far:
<?xml version="1.0" encoding="utf-8"?>
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:msxsl="urn:schemas-microsoft-com:xslt"
xmlns:soap="http://soap/envelope/"
>
<xsl:output method="xml" indent="no"/>
<xsl:template match="//soap:Body/*">
</xsl:template>
</xsl:stylesheet>
The following stylesheet:
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:soap="http://www.w3.org/2003/05/soap-envelope"
xmlns:m="http://www.example.org/stock">
<xsl:template match="/">
<xsl:apply-templates select="soap:Envelope/soap:Body/*"/>
</xsl:template>
<xsl:template match="#*|node()">
<xsl:copy>
<xsl:apply-templates select="#*|node()"/>
</xsl:copy>
</xsl:template>
</xsl:stylesheet>
Applied to this SOAP example from Wikipedia:
<soap:Envelope xmlns:soap="http://www.w3.org/2003/05/soap-envelope">
<soap:Header></soap:Header>
<soap:Body>
<m:GetStockPrice xmlns:m="http://www.example.org/stock">
<m:StockName>IBM</m:StockName>
</m:GetStockPrice>
</soap:Body>
</soap:Envelope>
Outputs the contents of the SOAP body (not including the body element itself):
<m:GetStockPrice xmlns:m="http://www.example.org/stock"
xmlns:soap="http://www.w3.org/2003/05/soap-envelope">
<m:StockName>IBM</m:StockName>
</m:GetStockPrice>