1

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

1 Answer 1

1

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.

Sign up to request clarification or add additional context in comments.

2 Comments

THANK YOU!!! I've been looking at this for a couple of days. I really appreciate your help!!
And I know what you're probably thinking - all that trouble over one little slash. :) Glad to help.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.