xsltweb-configelmah

Stopping XSLT including xmlns attribute when adding elements to XML file


Background: I am trying to script the configuration of Elmah so that, in production, I can run a script that will copy binaries and edit web.config file accordingly.

I decided to use XSLT to make the alterations to the web.config file. To start with I want to add a sectionGroup in the configSections element like so.

  <sectionGroup name="elmah">
    <section name="errorFilter" requirePermission="false" type="Elmah.ErrorFilterSectionHandler, Elmah" />
    ....
  </sectionGroup>

Here is my XSLT template

<?xml version="1.0" encoding="utf-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
    xmlns:msxsl="urn:schemas-microsoft-com:xslt" exclude-result-prefixes="msxsl"
    xmlns:con="http://schemas.microsoft.com/.NetConfiguration/v2.0"
>
    <xsl:output method="xml" indent="yes"/>

    <xsl:template match="@* | node()">
        <xsl:copy>
            <xsl:apply-templates select="@* | node()"/>
        </xsl:copy>
    </xsl:template>

  <!-- Add sectionGroup to configuration/configSections-->
  <xsl:template match="con:configSections[not (con:sectionGroup/@name='elmah')]">
    <xsl:copy>
      <xsl:apply-templates select="@* | node()"/>
      <xsl:comment>ELMAH</xsl:comment>
      <sectionGroup name="elmah" >
        <section name="security" requirePermission="false" type="Elmah.SecuritySectionHandler, Elmah" />
        <section name="errorLog" requirePermission="false" type="Elmah.ErrorLogSectionHandler, Elmah" />
        <section name="errorMail" requirePermission="false" type="Elmah.ErrorMailSectionHandler, Elmah" />
        <section name="errorFilter" requirePermission="false" type="Elmah.ErrorFilterSectionHandler, Elmah" />
      </sectionGroup>
      <xsl:comment>/ELMAH</xsl:comment>
    </xsl:copy>
  </xsl:template>
</xsl:stylesheet>

And it almost does what I want. It generates the following sectionGroup XML.

  <!--ELMAH-->
  <sectionGroup name="elmah" xmlns="" xmlns:con="http://schemas.microsoft.com/.NetConfiguration/v2.0">
    <section name="security" requirePermission="false" type="Elmah.SecuritySectionHandler, Elmah" />
    ....
  </sectionGroup>
  <!--/ELMAH-->

Note the xmlns attribute. The presence of this attribute really upsets ASP.Net (even though it is perfectly valid XML - albeit superfluous) and all requests result in a HTTP 500 error (see the section below for the error message). The only error message that I could get out of

Removing the xmlns attribute fixes this problem.

I could use xsl:element to generate the new XML but this leads to very verbose and hard to read XSL.

So my question is how to tell XSLT not to add the xmls attribute in the resulting XML?

Thanks in advance.


The error messages

For information here are the error messages that ASP/IIS gives us: -


The solution to my problem

Thanks to LarsH, Vincent Biragnet and Michael Kay for their responses, which between them have sorted out my problem.

Firstly - my XSLT as posted is wrong, as Michael and Vincent point out, the sectionGroup element should be in the namespace "http://schemas.microsoft.com/.NetConfiguration/v2.0".

To sort this, I defined the default namespace in my XSLT like so xmlns="http://schemas...".

But (why I do not know) the sectionGroup element is then output as

<sectionGroup name="elmah" xmlns:con="http://schemas.microsoft.com/.NetConfiguration/v2.0">

(Isn't the xmlns:con superfluous?). Anyway, the configuration parser barfs at the presence of xmlns:con.

But LarsH to the rescue - his suggestion suggestion of using exclude-result-prefixes="msxsl con" gets rid of those pesky things.

So the top of my (now working) XSLT now looks like this

<xsl:stylesheet version="1.0" 
    xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
    xmlns:msxsl="urn:schemas-microsoft-com:xslt" 
    xmlns:con="http://schemas.microsoft.com/.NetConfiguration/v2.0"
    xmlns="http://schemas.microsoft.com/.NetConfiguration/v2.0"
    exclude-result-prefixes="msxsl con"
>

Thanks again for everyone's help


Solution

  • First, if ASP.NET is upset merely by the presence of the xmlns="" pseudoattribute (as opposed to being upset because your content is in the wrong namespace), then that is a bug in ASP.NET and ought to be fixed. If your ELMAH content actually is in the wrong namespace, then of course that issue should be fixed (but AFAICT, ELMAH config content should be in no namespace, so yours is fine).

    It may help to add the exclude-result-prefixes attribute to your <xsl:stylesheet> start tag:

    exclude-result-prefixes="con"
    

    That should at least remove the xmlns:con="..." declaration from your output. See here for more info.

    However, since you are embedding the ELMAH XML (which is in no namespace) under some .NetConfiguration XML, which is in a namespace; if XSLT has decided to use the default namespace for the latter, then it has no choice but to use some sort of namespace declaration on the <sectionGroup> element... otherwise the the <sectionGroup> element will be in the .NetConfiguration namespace.

    You haven't shown us the <con:configSections> part of your output XML... that would be helpful in diagnosing the cause, and finding a solution. In particular, does your output XML have <con:configSections> (i.e. using the con prefix) or <configSections> (using the default namespace)?