title: How to replace namespace uri with xslt
body: <p>How do I replace the namespace uri of one or more elements of an XML message without knowing beforehand the namespace prefix that will be arbitrarily used by the sender?</p>
  
  <p>I know forms of this question have been asked many times, but every answer I find (here and in other sites) presupposes exact knowledge of a prefix.  Prefixes, by definition, are arbitrary, and the solution to this shouldn't require a hardened knowledge of the prefix used.</p>
  
  <p>I have a solution, but it results in junk I do not need in the output.  Simple input:</p>
  
  <pre><code>&lt;?xml version="1.0" encoding="UTF-8"?&gt;
  &lt;myThing xmlns:s="http://tempuri3.org/"&gt;
      &lt;s:thisThing&gt;
          &lt;thatThing xmlns="http://cheapCookies.org/"/&gt;
          &lt;anotherThing xmlns="http://kingkong.org"&gt;
              &lt;thisThing/&gt;
          &lt;/anotherThing&gt;
      &lt;/s:thisThing&gt;
  &lt;/myThing&gt;
  </code></pre>
  
  <p>This is the XSLT:</p>
  
  <pre><code>&lt;?xml version="1.0" ?&gt; 
  &lt;xsl:stylesheet version="1.0" 
      xmlns:xsl="http://www.w3.org/1999/XSL/Transform"&gt;
  
    &lt;xsl:param name="sourceNamespace" select="'http://tempuri3.org/'" /&gt; 
    &lt;xsl:param name="targetNamespace" select="'http://tempuri.org'"/&gt; 
  
    &lt;xsl:output method="xml" encoding="utf-8" indent="yes"/&gt; 
  
      &lt;xsl:template match="node() | @*" name="identity"&gt;
          &lt;xsl:copy&gt;
              &lt;xsl:apply-templates select="node() | @*" /&gt;
          &lt;/xsl:copy&gt;
      &lt;/xsl:template&gt;
  
      &lt;xsl:template match="*"&gt;
          &lt;xsl:choose&gt;
              &lt;xsl:when test="namespace-uri() = $sourceNamespace"&gt;
                  &lt;xsl:element name="{name()}" namespace="{$targetNamespace}"&gt;
                      &lt;xsl:apply-templates select="node() | @*"/&gt;
                  &lt;/xsl:element&gt;
              &lt;/xsl:when&gt;
  
              &lt;xsl:otherwise&gt;
                  &lt;xsl:call-template name="identity"/&gt;
              &lt;/xsl:otherwise&gt;
          &lt;/xsl:choose&gt;
  
      &lt;/xsl:template&gt;
  &lt;/xsl:stylesheet&gt;
  </code></pre>
  
  <p>This is the Output of the above XSLT:</p>
  
  <pre><code>&lt;?xml version="1.0" encoding="utf-8"?&gt;
  &lt;myThing xmlns:s="http://tempuri3.org/"&gt;
      &lt;s:thisThing xmlns:s="http://tempuri.org"&gt;
          &lt;thatThing xmlns="http://cheapCookies.org/" xmlns:s="http://tempuri3.org/"/&gt;
          &lt;anotherThing xmlns="http://kingkong.org" xmlns:s="http://tempuri3.org/"&gt;
              &lt;thisThing/&gt;
          &lt;/anotherThing&gt;
      &lt;/s:thisThing&gt;
  &lt;/myThing&gt;
  </code></pre>
  
  <p>This is the desired output:</p>
  
  <pre><code>&lt;?xml version="1.0" encoding="utf-8"?&gt;
  &lt;myThing xmlns:s="http://tempuri.org/"&gt;
      &lt;s:thisThing&gt;
          &lt;thatThing xmlns="http://cheapCookies.org/"/&gt;
          &lt;anotherThing xmlns="http://kingkong.org"&gt;
              &lt;thisThing/&gt;
          &lt;/anotherThing&gt;
      &lt;/s:thisThing&gt;
  &lt;/myThing&gt;
  </code></pre>