Since my actual transforms were relatively simple I developed this XSL transform:
<?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">
<xsl:output method="xml" indent="yes"/>
<xsl:variable name="xformPath">web.Prod.config</xsl:variable>
<xsl:variable name="xform" select="document($xformPath)"></xsl:variable>
<xsl:template match="@* | node()">
<xsl:copy>
<xsl:apply-templates select="@* | node()"/>
</xsl:copy>
</xsl:template>
<xsl:template name="output-transform">
<xsl:param name="xformNode" />
<xsl:variable name="key" select="@key" />
<xsl:choose>
<xsl:when test="$xformNode">
<xsl:copy-of select="$xformNode" />
</xsl:when>
<xsl:otherwise>
<xsl:copy>
<xsl:apply-templates select="@* | node()"/>
</xsl:copy>
</xsl:otherwise>
</xsl:choose>
</xsl:template>
<xsl:template match="/configuration/appSettings/add">
<xsl:variable name="key" select="@key" />
<xsl:call-template name="output-transform">
<xsl:with-param name="xformNode" select="$xform/configuration/appSettings/add[@key=$key]" />
</xsl:call-template>
</xsl:template>
<xsl:template match="/configuration/connectionStrings/add">
<xsl:variable name="name" select="@name" />
<xsl:call-template name="output-transform">
<xsl:with-param name="xformNode" select="$xform/configuration/connectionStrings/add[@name=$name]" />
</xsl:call-template>
</xsl:template>
<xsl:template match="/configuration/system.web/customErrors">
<xsl:call-template name="output-transform">
<xsl:with-param name="xformNode" select="$xform/configuration/system.web/customErrors" />
</xsl:call-template>
</xsl:template>
</xsl:stylesheet>
That has some obvious shortcomings,
- Items to be replaced must be manually defined
- Replaces with the entire element, not only the specified attributes
- Does not maintain children elements (e.g. I tried to change
system.web/compilation@debug
to false
but I lost all my system.web/compilation/assemblies
entries)
I plan to add this in a Command Line step, between my Visual Studio Build step and Copy Files step, and call either msxsl.exe or Saxon's HE transform engine.