Thursday 7 July 2011

[SOLVED] How To Stop XSL Outputting Unwanted Namespaces


Unwanted namespace in transformed XML
I'm using XSL quite a lot now and several times I've had an issue with namespaces in the output XML/XHTML. In particular if you're using xpath-functions then you might have the xmlns:fn namespace finding it's way into your output. I've finally found the solution and though I'd better post it before  I forget it.

Lets see some an example of the problem.



Problem
Here some XML:
<People>
  <Person name="Dave" />
  <Person name="Bob" />
</People>


and an XSL stylesheet:

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:fn="http://www.w3.org/2005/xpath-functions">
<xsl:output method="xml" indent="yes" />
  <xsl:template match="/" >
<DifferentXMLFormat>
   <List>
    <xsl:apply-templates select="/People/Person" />
   </List>
</DifferentXMLFormat>
  </xsl:template>


  <xsl:template match="Person" >
   <Item><xsl:value-of select="@name" /></Item>
  </xsl:template>


</xsl:stylesheet>




The output:
<?xml version="1.0"?>
<DifferentXMLFormat xmlns:fn="http://www.w3.org/2005/xpath-functions">
  <List>
    <Item>Dave</Item>
    <Item>Bob</Item>
  </List>
</DifferentXMLFormat>


Note the offending namespace in red.

Solution
One small tweak can sort this out:

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:fn="http://www.w3.org/2005/xpath-functions" exclude-result-prefixes="fn">
<xsl:output method="xml" indent="yes" />
  <xsl:template match="/" >
<DifferentXMLFormat>
   <List>
    <xsl:apply-templates select="/People/Person" />
   </List>
</DifferentXMLFormat>
  </xsl:template>

  <xsl:template match="Person">
   <Item><xsl:value-of select="@name" /></Item>
  </xsl:template>

</xsl:stylesheet>



The output new output:
<?xml version="1.0"?>
<DifferentXMLFormat>
  <List>
    <Item>Dave</Item>
    <Item>Bob</Item>
  </List>
</DifferentXMLFormat>


Viola! No namespace.