Reputation: 1188
I'd like to copy only header element with all subnodes and add to every subnode prefix "v11"(including header element)
Source xml:
<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/">
<soap:Body>
<ns3:createReservationRequest xmlns:ns3="ns3URL" xmlns:ns2="ns2URL">
<header>
<language isoCountryCode="US" isoLanguageCode="en"/>
<channel name="DT">
<subChannel name="WEBWB">
<subChannel name="WEBWB">
<subChannel name="Functester">
<subChannel name="ecom"/>
</subChannel>
</subChannel>
</subChannel>
</channel>
</header>
<ns3:agentInfo>
<ns2:agentDutyCode>PR</ns2:agentDutyCode>
</ns3:agentInfo>
</ns3:createReservationRequest>
</soap:Body>
</soap:Envelope>
Desired result xml:
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/"
xmlns:v1="v1URL"
xmlns:v11="v11URL">
<soapenv:Body>
<v1:createBookerEventRequest>
<v11:header>
<v11:channel name="DT">
<v11:subChannel name="WEBWB">
<v11:subChannel name="WEBWB">
<v11:subChannel name="Functester">
<v11:subChannel name="ecom"/>
</v11:subChannel>
</v11:subChannel>
</v11:subChannel>
</v11:channel>
</v11:header>
</v1:createBookerEventRequest>
</soapenv:Body>
</soapenv:Envelope>
I've tried to implement this using example from here . I've written the following xsl:
<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/"
xmlns:v11="v11URL">
<xsl:output method="xml" indent="yes" omit-xml-declaration="yes"/>
<xsl:template match="/">
<xsl:copy>
<xsl:apply-templates select="//*[local-name()='header']/*"/>
</xsl:copy>
</xsl:template>
<xsl:template match="//*[local-name()='header']/*">
<xsl:element name="v11:{name()}" inherit-namespaces="no">
<xsl:apply-templates select="node()|@*"/>
</xsl:element>
</xsl:template>
</xsl:stylesheet>
But it doesn't copy subchannels into result xml. And also adds unwanted "xmlns:v11="http://example.com/schema/common/ATPCommonServiceTypes/v1" attribute to header subnodes. Any help is appreciated
Upvotes: 1
Views: 3354
Reputation: 23627
I added a xmlns
declaration to agentDutyCode
since it is missing a namespace declaration:
<ns2:agentDutyCode xmlns:ns2="ns2URL">PR</ns2:agentDutyCode>
Using the source with this stylesheet (templates explained in the comments):
<xsl:stylesheet version="2.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/"
xmlns:v11="v11URL"
xmlns:v1="v1URL"
xmlns:ns3="ns3URL"
exclude-result-prefixes="ns3">
<xsl:output method="xml" indent="yes" omit-xml-declaration="yes"/>
<xsl:strip-space elements="*"/>
<!-- Copies Envelope and Body preserving their namespace -->
<xsl:template match="soap:Envelope | soap:Body">
<xsl:copy>
<xsl:apply-templates select="node()|@*"/>
</xsl:copy>
</xsl:template>
<!-- Creates the createReservationRequest element -->
<xsl:template match="ns3:createReservationRequest">
<v1:createBookerEventRequest>
<xsl:apply-templates/>
</v1:createBookerEventRequest>
</xsl:template>
<!-- Ignores language and agentInfo subtrees -->
<xsl:template match="language"/>
<xsl:template match="ns3:agentInfo"/>
<!-- Matches all other elements -->
<xsl:template match="*">
<xsl:element name="v11:{local-name()}" inherit-namespaces="no">
<xsl:apply-templates select="node()|@*"/>
</xsl:element>
</xsl:template>
<!-- Copies attributes -->
<xsl:template match="@*">
<xsl:copy>
<xsl:value-of select="."/>
</xsl:copy>
</xsl:template>
</xsl:stylesheet>
You will have this result:
<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/">
<soap:Body>
<v1:createBookerEventRequest xmlns:v11="v11URL" xmlns:v1="v1URL">
<v11:header>
<v11:channel name="DT">
<v11:subChannel name="WEBWB">
<v11:subChannel name="WEBWB">
<v11:subChannel name="Functester">
<v11:subChannel name="ecom"/>
</v11:subChannel>
</v11:subChannel>
</v11:subChannel>
</v11:channel>
</v11:header>
</v1:createBookerEventRequest>
</soap:Body>
</soap:Envelope>
Here is an XSLT Fiddle where you can see the result.
Upvotes: 2
Reputation: 167726
Here is my (edited) suggestion:
<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/"
xmlns:v1="v1URL"
xmlns:v11="v11URL"
xmlns:ns3="ns3URL"
exclude-result-prefixes="soap ns3">
<xsl:template match="@* | node()">
<xsl:copy>
<xsl:apply-templates select="@* , node()"/>
</xsl:copy>
</xsl:template>
<xsl:template match="/*">
<xsl:copy>
<xsl:copy-of select="document('')/xsl:stylesheet/namespace::*[local-name() = ('v1', 'v11')]"/>
<xsl:apply-templates select="@* , node()"/>
</xsl:copy>
</xsl:template>
<xsl:template match="*[not(namespace-uri())]">
<xsl:element name="v11:{local-name()}">
<xsl:apply-templates select="@* , node()"/>
</xsl:element>
</xsl:template>
<xsl:template match="ns3:createReservationRequest">
<v1:createBookerEventRequest>
<xsl:apply-templates select="@* , node()"/>
</v1:createBookerEventRequest>
</xsl:template>
<xsl:template match="ns3:agentInfo"/>
</xsl:stylesheet>
Upvotes: 2