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