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

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).

Related

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>

XSLT Soap Message

I can't change the name of tags in a SOAP response.
I saw a lot of postings about it, but I did not find an applicable solution.
My original XML is:
<?xml version="1.0" encoding="UTF-8"?>
<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/" xmlns:wsa="http://www.w3.org/2005/08/addressing">
<soap:Header>
<MessageID xmlns="http://www.w3.org/2005/08/addressing">uuid:4d6b87d8-fe14-4579-ac34-fe841c184a4b</MessageID>
<RelatesTo RelationshipType="Reply" xmlns="http://www.w3.org/2005/08/addressing">uuid:1f9b0c7e-f36c-4fa3-ac2b-2377b57b6634</RelatesTo>
<Action xmlns="http://www.w3.org/2005/08/addressing">http://xxx</Action>
</soap:Header>
<soap:Body xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<OP1 xmlns="http://xxx/">
<OPR>
<OPO>
<Cod>..</Cod>
<A1>hi my...</A1>
</OPO>
</OPR>
</OP1>
</soap:Body>
</soap:Envelope>
I want to change A1 for ANAME.
My xsl is
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/" xmlns:wsa="http://www.w3.org/2005/08/addressing">
<xsl:template match="#*|node()">
<xsl:copy>
<xsl:apply-templates select="#* | node()" />
</xsl:copy>
</xsl:template>
<xsl:template match="A1">
<ANAME><xsl:apply-templates /></ANAME>
</xsl:template>
</xsl:stylesheet>
Thanks!
Just add a named namespace declaration for your namespace "http://xxx/" to your stylesheet element like this:
xmlns:aaa="http://xxx/"
Then your can match the A1 elements with aaa:A1 in your template:
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/" xmlns:wsa="http://www.w3.org/2005/08/addressing" xmlns:aaa="http://xxx/">
<xsl:template match="#*|node()">
<xsl:copy>
<xsl:apply-templates select="#* | node()" />
</xsl:copy>
</xsl:template>
<xsl:template match="aaa:A1">
<xsl:element name="ANAME" namespace="http://xxx/">
<xsl:apply-templates />
</xsl:element>
</xsl:template>
</xsl:stylesheet>
Partial output:
...
<soap:Body xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<OP1 xmlns="http://xxx/">
<OPR>
<OPO>
<Cod>..</Cod>
<ANAME>hi my...</ANAME>
</OPO>
</OPR>
</OP1>
</soap:Body>

Adding soap envelope or remain same using XSLT 1.0

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>

xslt Removing particular namespace from root only

I want to remove namespace (xmlns="http://www.cric.com") in the root element and also the comments.
Input xml looks like this
<?xml version="1.0" encoding="UTF-8"?>
<AM xmlns="http://www.cric.com" name="Asmkl">
<!-- Sets a new value to the existing parameter -->
<set>
<Payload>
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:web="http://www.webserviceX.NET">
<soapenv:Header />
<soapenv:Body>
<web:GetCitiesByCountry>
<!--Optional:-->
<web:CountryName>india</web:CountryName>
</web:GetCitiesByCountry>
</soapenv:Body>
</soapenv:Envelope>
</Payload>
<Verb>POST</Verb>
</Set>
</AM>
I have tried
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
<xsl:template match="*[namespace-uri() = 'http://www.cric.com']">
<xsl:choose>
<xsl:when test="local-name(.)='root'">
<xsl:element name="root">
<xsl:apply-templates select="#* | node()"/>
</xsl:element>
</xsl:when>
<!-- Copy other elemnts -->
<xsl:otherwise>
<xsl:element name="{name()}">
<xsl:apply-templates select="#* | node()"/>
</xsl:element>
</xsl:otherwise>
</xsl:choose>
</xsl:template>
<!-- Copy the rest -->
<xsl:template match="#* | node()">
<xsl:copy>
<xsl:apply-templates select="#* | node()"/>
</xsl:copy>
</xsl:template>
</xsl:stylesheet>
This stylesheet removes from root but adding the namespace in soapenv:Envelope tag.
Desired output is
<?xml version="1.0" encoding="UTF-8"?>
<AM name="Asmkl">
<Set>
<Payload>
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:web="http://www.webserviceX.NET">
<soapenv:Header />
<soapenv:Body>
<web:GetCitiesByCountry>
<web:CountryName>india</web:CountryName>
</web:GetCitiesByCountry>
</soapenv:Body>
</soapenv:Envelope>
</Payload>
<Verb>POST</Verb>
</Set>
</AM>
but I am getting
<?xml version="1.0" encoding="UTF-8"?><AM name="Asmkl">
<!-- Sets a new value to the existing parameter -->
<Set>
<Payload>
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:web="http://www.webserviceX.NET" xmlns="http://www.cric.com">
<soapenv:Header/>
<soapenv:Body>
<web:GetCitiesByCountry>
<!--Optional:-->
<web:CountryName>india</web:CountryName>
</web:GetCitiesByCountry>
</soapenv:Body>
</soapenv:Envelope>
</Payload>
<Verb>POST</Verb>
</Set>
</AM>
Kindly suggest. XSLT processor is 1.0
How about:
XSLT 1.0
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes"/>
<xsl:strip-space elements="*"/>
<!-- move elements in the default namespace into no namespace -->
<xsl:template match="*[namespace-uri() = 'http://www.cric.com']">
<xsl:element name="{local-name()}">
<xsl:copy-of select="#*"/>
<xsl:apply-templates select="*"/>
</xsl:element>
</xsl:template>
<!-- "copy" all other elements, without copying the default namespace -->
<xsl:template match="*">
<xsl:element name="{name()}" namespace="{namespace-uri()}">
<xsl:copy-of select="#*"/>
<xsl:apply-templates select="*"/>
</xsl:element>
</xsl:template>
</xsl:stylesheet>
Applied to your example (after correcting <set> to <Set>!), the result will be:
<?xml version="1.0" encoding="UTF-8"?>
<AM name="Asmkl">
<Set>
<Payload>
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/">
<soapenv:Header/>
<soapenv:Body>
<web:GetCitiesByCountry xmlns:web="http://www.webserviceX.NET">
<web:CountryName/>
</web:GetCitiesByCountry>
</soapenv:Body>
</soapenv:Envelope>
</Payload>
<Verb/>
</Set>
</AM>
Note:
I want to remove namespace (xmlns="http://www.cric.com") in the root
element
I am not sure if you realize that the default namespace declared in the root element:
<AM xmlns="http://www.cric.com" name="Asmkl">
is also inherited by the Set and Payload elements.

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>