Web.config transformation and search and replace

2.6k views Asked by At

I need to switch out an IP address in multiple WCF services in web.config. With web.config transformation, is there any way, besides specifying each an every address by xpath, to create a search and replace statement. E.g. switch out IP address 1.2.3.4 with 4.3.2.1 for all instances of 1.2.3.4

1

There are 1 answers

2
Piotr Owsiak On BEST ANSWER

Say your Web.config is something like this (a simplified scenario, but // in XPath works everywhere):

<configuration>
    <endpoint address="1.2.3.4" />
    <endpoint address="1.2.3.4" />
    <endpoint address="1.2.3.4" />
    <endpoint address="1.2.3.4" />
</configuration>

then you will need something like this:

<?xml version="1.0"?>    
<!-- For more information on using web.config transformation visit http://go.microsoft.com/fwlink/?LinkId=125889 -->    
<configuration xmlns:xdt="http://schemas.microsoft.com/XML-Document-Transform">

    <replaceAll>
        <endpontAddresses xdt:Locator="XPath(//endpoint[@address='1.2.3.4'])" xdt:Transform="SetAttributes(address)" address="4.3.2.1" />
    </replaceAll>

</configuration>

NOTE: this XPath will look for every element in the whole Web.config and check whether given element has address attribute with value equal to "1.2.3.4". If you need something more general then try this:

<?xml version="1.0"?>
    <!-- For more information on using web.config transformation visit http://go.microsoft.com/fwlink/?LinkId=125889 -->    
    <configuration xmlns:xdt="http://schemas.microsoft.com/XML-Document-Transform">

        <replaceAll>
            <endpontAddresses xdt:Locator="XPath(//*[@address='1.2.3.4'])" xdt:Transform="SetAttributes(address)" address="4.3.2.1" />
        </replaceAll>

    </configuration>

This will look at every XML element (due to the asterisk: *) and check whether it has address attribute with value equal to "1.2.3.4". So this will work for a file like this:

<configuration>
    <endpoint name="serviceA" address="1.2.3.4" />
    <endpoint name="serviceB" address="1.2.3.4" />
    <endpoint name="serviceC" address="1.2.3.4" />
    <endpoint2 address="1.2.3.4" />
    <endpoint3 address="1.2.3.4" />
    <endpoint4 address="1.2.3.4" />

    <innerSection>
    <endpoint address="1.2.3.4" />
    <anotherEndpoint address="1.2.3.4" />
    <sampleXmlElement address="1.2.3.4" />
    </innerSection>
</configuration>

Now if you want to limit substitutions to a certain section i.e. <system.serviceModel> then you can use an XPath like this:

    <endpontAddresses xdt:Locator="XPath(/configuration/system.serviceModel//*[@address='1.2.3.4'])" xdt:Transform="SetAttributes(address)" address="4.3.2.1" />

This will update addresses only in <system.serviceModel> section

<configuration>
    <endpoint name="serviceA" address="1.2.3.4" />
    <endpoint name="serviceB" address="1.2.3.4" />
    <endpoint name="serviceC" address="1.2.3.4" />
    <endpoint2 address="1.2.3.4" />
    <endpoint3 address="1.2.3.4" />
    <endpoint4 address="1.2.3.4" />

    <innerSection>
    <endpoint address="1.2.3.4" />
    <anotherEndpoint address="1.2.3.4" />
    <sampleXmlElement address="1.2.3.4" />
    </innerSection>

    <system.serviceModel>
    <endpoint name="serviceB" address="1.2.3.4" />
    <endpoint name="serviceC" address="1.2.3.4" />
    <endpoint2 address="1.2.3.4" />
    <innerSection>
      <endpoint address="1.2.3.4" />
      <anotherEndpoint address="1.2.3.4" />
      <sampleXmlElement address="1.2.3.4" />
      </innerSection>
    </system.serviceModel>

</configuration>

Give those a try and choose the one that suits your needs most.

NOTE: This has a limitation that you need to specify what is the name of the attribute that contains the IP (1.2.3.4) but I think its better to be explicit rather than have magic happen here. If you have many attibute names just repeat the