NigelB
NigelB

Reputation: 23

How can I add <configSections> to web.config using xslt

I need to modify a web.config using xslt. We have no direct access to the actual web.config pre or post transform. The only mechanism to modify it is using xslt.

I have written an xslt that will add other nodes successfully. If they exist, I can add child nodes, or create the parent node, complete with child nodes if necessary.

The problem is with <configSections> It needs to be the first node under <configuration> or IIS will complain. This wouldn't be a problem if it was guaranteed to exist, but it's not. No matter what I've tried, I can't force the result to reliably place the <configSections> node as the first node.

In my sample below, if <configSections> doesn't exist, it puts the new <configSections> at the top, but if it does exist, it adds it at some arbitrary place (within the <configuration> tag).

I've searched everywhere, but can't find a solution to this seemingly simple problem, so I'm hoping some XSLT expert will show me it really is simple. It should be noted I'm a complete dummy at xslt(!)

Sample source xml:

    <configuration>
       <appSettings>
       ...
       </appSettings>
       <otherStuff/>
    </configuration>

My Xslt:

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

<!--If <configSections> exists, then add in my <section> node-->
<xsl:template match="configSections">
    <xsl:copy>
        <xsl:apply-templates select="@*"/>
        <section name="mySectionHandler"/>
        <xsl:apply-templates select="node()"/>
    </xsl:copy>
</xsl:template>

<xsl:template match="configuration">
    <xsl:copy>
        <xsl:apply-templates select="@*"/>      
        <xsl:if test="not(configSections)">
            <configSections>
                <section name="mySection"/>
           </configSections>
        </xsl:if>
        <xsl:if test="not(system.web)">
            <system.web>
                <httpRuntime executionTimeout="180" maxRequestLength="65536"/>
            </system.web>
        </xsl:if>
        <xsl:apply-templates select="node()"/>
    </xsl:copy>
</xsl:template>

Upvotes: 2

Views: 733

Answers (1)

Tim C
Tim C

Reputation: 70648

I am not sure what you mean by adding the configSections at an arbitrary place if it does exist. You XSLT would put it in the same place in the output, with the exception of when a system.web doesn't exist, as your XSLT would then put a system.web before any existing configSections

Anyway, try this XSLT. This should select any existing configSections first, adding one if it doesn't exist. Then at the end, it can select all other elements.

<xsl:template match="configuration">
    <xsl:copy>
        <xsl:apply-templates select="@*"/>  
        <xsl:apply-templates select="configSections"/>
        <xsl:if test="not(configSections)">
            <configSections>
                <section name="mySection"/>
           </configSections>
        </xsl:if>
        <xsl:if test="not(system.web)">
            <system.web>
                <httpRuntime executionTimeout="180" maxRequestLength="65536"/>
            </system.web>
        </xsl:if>
        <xsl:apply-templates select="node()[not(self::configSections)]"/>
    </xsl:copy>
</xsl:template>

Upvotes: 2

Related Questions