Question

I would like to apply a transformation if and only if a matched element does not exist in the target. Trying various xpath expressions using http://webconfigtransformationtester.apphb.com/ but no luck so far.

E.g. if the target web.config looks like this:

<configuration>
  <system.web>
    <compilation debug="true" />
  </system.web>
</configuration>

then the output should look like this:

<configuration>
  <connectionStrings>
    <add name="MyCs" provider="System.Data.SqlClient" connectionString="" />
    <add name="SomeOtherCs" provider="System.Data.SqlClient" connectionString="" />
  </connectionStrings>
  <system.web>
    <compilation debug="true" />
  </system.web>
</configuration>

But if the target looks like this:

<configuration>
  <connectionStrings>
    <add name="MyCs" provider="System.Data.IChangedIt" connectionString="my connection string here" />
  </connectionStrings>
  <system.web>
    <compilation debug="true" />
  </system.web>
</configuration>

then the result of the transformation should look like this:

<configuration>
  <connectionStrings>
    <add name="MyCs" provider="System.Data.IChangedIt" connectionString="my connection string here" />
    <add name="SomeOtherCs" provider="System.Data.SqlClient" connectionString="" />   
  </connectionStrings>
  <system.web>
    <compilation debug="true" />
  </system.web>
</configuration>

In other words, I just want to add the named connection string to configuration but let the administrator fill it in with his own values. I thought it would as simple as xdt:Transform="Insert" xdt:Locator="XPath(count(/configuration/connectionStrings)=0)" (to add a cs config section if none existed) but apparently not.

Was it helpful?

Solution

Use xdt:Transform="InsertIfMissing" with the XmlTransform task in VS2012. It doesn't look like Microsoft has updated their documentation to reflect this yet.

OTHER TIPS

In my case xdt:Transform="InsertIfMissing" did not work without xdt:Locator="Match(name)"

Try this alternative transformation for xdt:Transform="InsertIfMissing" :

<?xml version="1.0"?>
<configuration xmlns:xdt="http://schemas.microsoft.com/XML-Document-Transform">
  <nodeToInsertIfMissing xdt:Transform="Insert" />
  <nodeToInsertIfMissing xdt:Transform="Remove" xdt:Locator="XPath(/configuration/nodeToInsertIfMissing[2])" />
</configuration>

It should works following MSDN documentation:

Insert - adds the element that is defined in the transform file as a sibling to the selected element or elements. The new element is added at the end of any collection.

So, if the node already exists, we add the second one and then remove this node (2nd). Otherwise, we add the new, unique node but remove operation will fail.

Note: It seems not working with NuGet *.(un)install.xdt transformation. InsertIfMissing too.

Confirmed working in VS2015 and Package Manager Console Host Version 3.4.4.1321 (you can find this when you open the Package Manager Console).

This will insert if 'configuration\connectionStrings\add\@name' does not exist.

The app.config.install.xdt:

<?xml version="1.0" encoding="utf-8" ?>
<configuration xmlns:xdt="http://schemas.microsoft.com/XML-Document-Transform">
    <connectionStrings xdt:Transform="InsertIfMissing">
        <add name="MyCs" provider="System.Data.SqlClient" connectionString="" xdt:Transform="InsertIfMissing" xdt:Locator="Match(name)"/>
    </connectionStrings>
</configuration>

The .nuspec file:

<files>
    <file src="app.config.install.xdt" target="content\app.config.install.xdt" />

Use xdt:Transform="Remove" followed by xdt:Transform="Insert" transforms. The xdt:Transform="InsertIfMissing" suggested elsewhere did not work for me, looks like its version specific.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top