Reputation: 11
I have a SOAP request that I am trying to transform with XSLT. I want to add namespace qualifiers to each element in the request. There are two different namespaces that need I need to user. Here is the XML I'm trying to tranform:
<soapenv:Envelope xmlns:soapenv="http://www.w3.org/2003/05/soap-envelope" >
<soapenv:Header/>
<soapenv:Body>
<PingRq>
<RqUID>1</RqUID>
<RequestContext>
<ClientUserID>1</ClientUserID>
<ClientName>Big Company</ClientName>
<ClientApplication>
<AppName>TestApp</AppName>
<AppVersion>1</AppVersion>
</ClientApplication>
<ClientLangPref>En-US</ClientLangPref>
<ClientDt>Mar-29-2013</ClientDt>
</RequestContext>
</PingRq>
</soapenv:Body>
</soapenv:Envelope
Here is what I want to transform it to:
<soapenv:Envelope xmlns:soapenv="http://www.w3.org/2003/05/soap-envelope" >
<soapenv:Header/>
<soapenv:Body>
<PingRq namespace="http://www.ns1.com">
<RqUID namespace="http://www.ns2.com">1</RqUID>
<RequestContext namespace="http://www.ns2.com">
<ClientUserID namespace="http://www.ns2.com">1</ClientUserID>
<ClientName namespace="http://www.ns2.com">Big Company</ClientName>
<ClientApplication namespace="http://www.ns2.com">
<AppName namespace="http://www.ns2.com">TestApp</AppName>
<AppVersion namespace="http://www.ns2.com">1</AppVersion>
</ClientApplication>
<ClientLangPref namespace="http://www.ns2.com">En-US</ClientLangPref>
<ClientDt namespace="http://www.ns2.com">Mar-29-2013</ClientDt>
</RequestContext>
</PingRq>
</soapenv:Body>
</soapenv:Envelope>
Here is my style sheet
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="2.0"
xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/">
<xsl:template match="@*|node()">
<xsl:copy>
<xsl:apply-templates select = "@*|node()" />
</xsl:copy>
</xsl:template>
<xsl:template match="PingRq">
<xsl:element name="{local-name()}" namespace="http://www.ns1.com">
<xsl:apply-templates select="@* | node()"/>
</xsl:element>
</xsl:template>
<xsl:template match="PingRq/*">
<xsl:element name="{local-name()}" namespace="http://www.ns2.com">
<xsl:apply-templates select="@*|node()"/>
</xsl:element>
</xsl:template>
</xsl:stylesheet>
Here is the result I get.
<?xml version="1.0" encoding="UTF-8"?>
<soapenv:Envelope xmlns:soapenv="http://www.w3.org/2003/05/soap-envelope">
<soapenv:Header/>
<soapenv:Body>
<PingRq xmlns="http://www.ns1.com">
<RqUID xmlns="http://www.ns2.com">1</RqUID>
<RequestContext xmlns="http://www.ns2.com">
<ClientUserID xmlns="">1</ClientUserID>
<ClientName xmlns="">Big Company</ClientName>
<ClientApplication xmlns="">
<AppName>TestApp</AppName>
<AppVersion>1</AppVersion>
</ClientApplication>
<ClientLangPref xmlns="">En-US</ClientLangPref>
<ClientDt xmlns="">Mar-29-2013</ClientDt>
</RequestContext>
</PingRq>
</soapenv:Body>
</soapenv:Envelope>
I can't figure out why I'm getting the empty namespace attributes in the descendants. Anyone got any ideas???
Upvotes: 1
Views: 1348
Reputation: 101680
The PingRq/*
xpath only matches direct children of the PingRq
element. To put all of its descendant elements in a certain namespace, you can do this:
<xsl:template match="PingRq//*">
<xsl:element name="{local-name()}" namespace="http://www.ns2.com">
<xsl:apply-templates select="@*|node()"/>
</xsl:element>
</xsl:template>
Note that the result does not show the namespace declarations on all the descendants:
<soapenv:Envelope xmlns:soapenv="http://www.w3.org/2003/05/soap-envelope">
<soapenv:Header />
<soapenv:Body>
<PingRq xmlns="http://www.ns1.com">
<RqUID xmlns="http://www.ns2.com">1</RqUID>
<RequestContext xmlns="http://www.ns2.com">
<ClientUserID>1</ClientUserID>
<ClientName>Big Company</ClientName>
<ClientApplication>
<AppName>TestApp</AppName>
<AppVersion>1</AppVersion>
</ClientApplication>
<ClientLangPref>En-US</ClientLangPref>
<ClientDt>Mar-29-2013</ClientDt>
</RequestContext>
</PingRq>
</soapenv:Body>
</soapenv:Envelope>
But this is to be expected, because the elements under RequestContext
are inheriting their namespace from their parent.
Upvotes: 1