update 3rd party's .config transformation's from installer
I have 2 .config files that have to be configured. One is a web.config
and one is an app.config
, both of these files are from a 3rd party vendor that our code runs inside. So we need to make adjustments to it so it sees our code.
My plan was to use xslt to take our .config file and merge it into the 3rd party one.
I've seen a few examples on how to do this type of thing with msbuild, but since we are doing it on site, we are going to have to do it with an installer. Any help would be appreciated.
Example: We are starting out with:
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<runtime>
<gcServer enabled="true"/>
</runtime>
</configuration>
Custom Section
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<configSections>
<section name="productName" type="company.productName, company, Version=1.0.0.0, Culture=neutral, PublicKeyToken=d9072a6c5128d57c" />
</configSections>
<p开发者_如何学编程roductName defaultProvider="Provider1">
<providers>
<clear />
<add name="Provider1" type="Company.Product.Authentication.Provider1, Company.Product, Version=1.0.0.0, Culture=neutral, PublicKeyToken=d9072a6c5128d57c" hostName="localhost:5555" />
<add name="Provider2" type="Company.Product.Authentication.Provider2, Company.Product, Version=1.0.0.0, Culture=neutral, PublicKeyToken=d9072a6c5128d57c" hostName="demo.example.com" />
</providers>
</productName>
</configuration>
And ending with:
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<configSections>
<section name="productName" type="company.productName, company, Version=1.0.0.0, Culture=neutral, PublicKeyToken=d9072a6c5128d57c" />
</configSections>
<productName defaultProvider="Provider1">
<providers>
<clear />
<add name="Provider1" type="Company.Product.Authentication.Provider1, Company.Product, Version=1.0.0.0, Culture=neutral, PublicKeyToken=d9072a6c5128d57c" hostName="localhost:5555" />
<add name="Provider2" type="Company.Product.Authentication.Provider2, Company.Product, Version=1.0.0.0, Culture=neutral, PublicKeyToken=d9072a6c5128d57c" hostName="demo.example.com" />
</providers>
</productName>
<runtime>
<gcServer enabled="true"/>
</runtime>
</configuration>
This stylesheet:
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:template match="/">
<xsl:apply-templates select="document('test.xml')/*">
<xsl:with-param name="pContext" select="*"/>
</xsl:apply-templates>
</xsl:template>
<xsl:template match="*[*]">
<xsl:param name="pContext" select="/.."/>
<xsl:variable name="vCurrent" select="."/>
<xsl:copy>
<xsl:copy-of select="@*"/>
<xsl:copy-of select="$pContext/@*"/>
<xsl:for-each select="*">
<xsl:apply-templates select=".">
<xsl:with-param name="pContext"
select="$pContext/*[name()=name(current())]"/>
</xsl:apply-templates>
</xsl:for-each>
<xsl:for-each select="$pContext/*">
<xsl:apply-templates
select="(.)[not($vCurrent/*[name()=name(current())])]"/>
</xsl:for-each>
</xsl:copy>
</xsl:template>
<xsl:template match="*[not(*)]">
<xsl:param name="pContext" select="/.."/>
<xsl:copy>
<xsl:copy-of select="@*"/>
<xsl:copy-of select="$pContext/@*"/>
<xsl:apply-templates
select="node()[not($pContext)]|$pContext/node()"/>
</xsl:copy>
</xsl:template>
</xsl:stylesheet>
With this input:
<configuration>
<runtime>
<gcServer enabled="true"/>
</runtime>
</configuration>
And this test.xml
:
<configuration>
<configSections>
<section name="productName" type="company.productName, company, Version=1.0.0.0, Culture=neutral, PublicKeyToken=d9072a6c5128d57c" />
</configSections>
<productName defaultProvider="Provider1">
<providers>
<clear />
<add name="Provider1" type="Company.Product.Authentication.Provider1, Company.Product, Version=1.0.0.0, Culture=neutral, PublicKeyToken=d9072a6c5128d57c" hostName="localhost:5555" />
<add name="Provider2" type="Company.Product.Authentication.Provider2, Company.Product, Version=1.0.0.0, Culture=neutral, PublicKeyToken=d9072a6c5128d57c" hostName="demo.example.com" />
</providers>
</productName>
</configuration>
Output:
<configuration>
<configSections>
<section name="productName" type="company.productName, company, Version=1.0.0.0, Culture=neutral, PublicKeyToken=d9072a6c5128d57c"></section>
</configSections>
<productName defaultProvider="Provider1">
<providers>
<clear></clear>
<add name="Provider1" type="Company.Product.Authentication.Provider1, Company.Product, Version=1.0.0.0, Culture=neutral, PublicKeyToken=d9072a6c5128d57c" hostName="localhost:5555"></add>
<add name="Provider2" type="Company.Product.Authentication.Provider2, Company.Product, Version=1.0.0.0, Culture=neutral, PublicKeyToken=d9072a6c5128d57c" hostName="demo.example.com"></add>
</providers>
</productName>
<runtime>
<gcServer enabled="true"></gcServer>
</runtime>
</configuration>
Note: Three rules. Document root rule: change the traversing tree to a source needing update and keep input source as $pContext
. Element with elements children rule: copy itself with attributes, update attributes with $pContext
's attributes (this is done by the processor because creating attributes rules), apply templates to elements children with new $pContext
(a child of old $pContext
with the same name), apply templates to $pContext
's children wich don't match any children's names. Element without elements children rule: copy itself with attributes updated with $pContext
attributes, if there is a node in $pContext
copy it, thus replacing element content (or even stripping if you have an empty element in $pContext
).
精彩评论