Visual Studio XML File Transformation Not Just For Web.Config

Being able to manage environment settings can be such a pain sometimes, especially when your doing it manually.  As of Visual Studio 2010 you are now able to associate environment specific settings based on a build configuration.  Imagine that you have a developement, QA, and production environment each having different database connections strings, log file paths, etc.  It would be nice to set this once and let the build determine the right output for you app.config file, no?  Well this feature is built in to web projects by default, but can be extended to any type of xml file.  There are a few steps to get it working but I will describe them below.  Most of these steps are based on this article XDT (web.config) Transforms in non-web projects which explains the general process and has an example attached.  There are a few items I will discuss which are not included in this article.

Prerequisites

  1. Visual Studio 2010 which has web projects (this conatins the TransfromXml build tasks).
  2. Create a folder %ProgramFiles (x86)%\MSBuild\Custom.  Download TransormFiles.targets and save to this directory with name TransformFiles.targets

Solution

In the solution below I will be use a WebForms project with additional xml files along with the default web.config file, a web.sitemap and a myfile.xml.  My project looks like the image below.

image

1.  Add the <Import> for TranformFiles.targets to you project file. 

Right click on you project and select “Unload project”, project should unload and be grayed out.  Right click again and select “Edit xxx.csproj” where xxx is your project name.  The project file will open and at the end of it put

<Import Project="$(MSBuildExtensionsPath)\Custom\TransformFiles.targets" />

image

2.  Update project file so that non app.config XML files’ (web.config in web project) are nested under the transformed file.  We’ll use the <DebendentUpon> element for each build file. For example a web.sitemap will have a web.release.sitemap if you are transforming you sitemap.

image

3.  Add the <TransormOnBuild> node to any XML file that is not a web.config file, this includes app.config files if you are not using a web project!  You only need to add this node to the files that have transformations applied.  For example, the web.sitemap will get this but the web.release.sitemap won’t.

image

4.  If you are using a web site project add the <CopyToOutputDirectory> to all XML files that will be transformed, other than the web.config file.  This will copy the transformed files to the bin folder of you build since it won’t copy the transformation to the same place as web.config file, unfortunately.  After the build you’ll have to manually copy these to their respective destinations.  Fortunately the output in the bin folder will have all the correct paths for these XML files.

image

imageProject view after steps 2-4

5.  Add the XML transform namespace http://schemas.microsoft.com/XML-Document-Transform to all you transform files.  If it’s a web project, remove the xmlns namespace in the root node of the web.sitemaps; if you don’t the transformation will not work on these files.  See Web.config Transformation Syntax for Web Application Project for the different transformation capabilities.

image

image 

6.  Build you code.  You should now see the transformation you applied.

1 comment:

Grant_C said...

Thanks for that, very helpful. Unfortunately the 'After the build you’ll have to manually copy these to their respective destinations' bit is a problem for me - it's easier to manually change the config file than copy it after deployment.

Shame MS didn't include this in the standard transform functionality, must be a common use case.