Date: 10-feb-05

Last updated: 05-may-05

Author: Pieter R. Siegers

NOTE: a better way to implement the functionality described below would be using a separate configuration class, which will be my focus of the next article on this subject.

This short article will describe how to dynamically update app.config and the dynamically generated <appName>.exe.config, using XML and XSLT. Both operations are needed when you want to change the config file but don't want to restart the application AFTER the next time you run the application again.

Being exactly the same and being both just plain XML, using one single stylesheet will suffice to do the job.

So say I've got an input XML like this (which resembles my actual app.config):

 

<?xml version="1.0" encoding="utf-8"?>

<configuration>

<appSettings>

<add key="BasePath" value="E:\MyWB5\" />

<add key="lstTOC.MultiColumn" value="False" />

<add key="strSubFolderImg" value="figs" />

<add key="strServerIntranetAleph" value="http://edtimd041sl/libros/" />

<add key="strServerIntranetAlephUNC" value="\\edtimd041sl\home\libros" />

<add key="strBookTitle" value="XSLT and XPATH A Guide to XML Transformations" />

</appSettings>

</configuration>

 

and I would like to change the book title "strBookTitle" into something else and leave everything else the same, then the following XSLT stylesheet:

 

<?xml version='1.0' ?>

<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">

<xsl:output method="xml" indent="yes" encoding="utf-8" />

<xsl:param name="strBookTitle" />

<xsl:template match="/">

<xsl:apply-templates select="configuration">

</xsl:apply-templates>

</xsl:template>

<xsl:template match="configuration">

<configuration>

<appSettings>

<add key="BasePath" value="E:\MyWB5\" />

<add key="lstTOC.MultiColumn" value="False" />

<add key="strSubFolderImg" value="figs" />

<add key="strServerIntranetAleph" value="http://edtimd041sl/libros/" />

<add key="strServerIntranetAlephUNC" value="\\edtimd041sl\home\libros" />

<add key="strBookTitle">

<xsl:attribute name="value">

<xsl:value-of select="$strBookTitle" />

</xsl:attribute>

</add>

</appSettings>

</configuration>

</xsl:template>

</xsl:stylesheet>

 

will do just that. It uses an input parameter that contains the new book title.

The code I used to perform both the app.config and <appName>.exe.config in .NET 1.x is as follows (note that of each there will be small documents to download directly):

 

<appName>.exe.config:

string strAppBasePath = Application.StartupPath;

XmlDocument xd = new XmlDocument();

xd.Load(strAppBasePath + @"\xml\config.xml");

XslTransform xt = new XslTransform();

xt.Load(strAppBasePath + @"\xsl\config.xsl");

XmlTextWriter writer = new XmlTextWriter(strAppBasePath + @"\MyWB5.exe.config", System.Text.Encoding.ASCII);

writer.Formatting = Formatting.Indented;

writer.Indentation = 2;

XsltArgumentList xal = new XsltArgumentList();

xal.AddParam("strBookTitle", "", strBookTitle);

xt.Transform(xd, xal, writer, null);

writer.Close();

 

app.config:

string strAppBasePathAppConf = Application.StartupPath.Substring(0, Application.StartupPath.Length - 10);

XmlDocument xd2 = new XmlDocument();

xd2.Load(strAppBasePath + @"\xml\config.xml");

XslTransform xt2 = new XslTransform();

xt2.Load(strAppBasePath + @"\xsl\config.xsl");

XmlTextWriter writer2 = new XmlTextWriter(strAppBasePathAppConf + @"\app.config", System.Text.Encoding.ASCII);

writer2.Formatting = Formatting.Indented;

writer2.Indentation = 2;

XsltArgumentList xal2 = new XsltArgumentList();

xal2.AddParam("strBookTitle", "", strBookTitle);

xt2.Transform(xd2, xal2, writer2, null);

writer.Close();

 

Note that the subfolders xml and xsl mentioned in the code need to exist as children of the StartupPath; in the case of Debug Mode, this is the folder ..\bin\Debug\.

Questions? Email me at 'mail <at> pietsieg.com'!

Cheers, Pieter