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@debugtofalsebut I lost all mysystem.web/compilation/assembliesentries)
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.