Common Transforms
Transforms can be used to dynamically alter the
contents of your xml config files at compile time. Because we will be
leveraging the results of the transform as part of a parameterized release
pipeline, the values injected into your config file will simply be tokens as
placeholders and identifiers for the values to be set at deploy time.
Transforms are performed based on both a transform and a locator attribute,
although in some cases, the locator attribute can be omitted. Below is a
simple example for tokenizing the compilation debug setting under the
system.web node:
Original setting:
<system.web>
<compilation debug="true">
...
</compilation>
</system.web>
Transform:
<system.web>
<compilation xdt:Transform="SetAttributes" debug="false" />
...
</system.web>
Result:
<system.web>
<compilation debug="false">
...
</compilation>
</system.web>
In this case, the transform being used is
SetAttributes and the attribute being set is debug. Alternatively, you could
use the following transform to achieve equivalent results.
Transform:
<system.web>
<compilation xdt:Transform="RemoveAttributes(debug)" />
...
</system.web>
Result:
<system.web>
<compilation>
...
</system.web>
In this case, the RemoveAttributes transform is
used and the specific attribute to be removed from the node is debug
Another example is the customErrors node.
Original setting:
<customErrors defaultRedirect="GenericError.htm" mode="On" />
Transform:
<customErrors xdt:Transform="Replace"
mode="RemoteOnly"
defaultRedirect="~/UI/ApplicationException.aspx">
<error statusCode="500" redirect="InternalError.aspx"/>
<error statusCode="404" redirect="NotFound.aspx"/>
</customErrors>
Result:
<customErrors mode="RemoteOnly" defaultRedirect="~/UI/ApplicationException.aspx">
<error statusCode="500" redirect="InternalError.aspx"/>
<error statusCode="404" redirect="NotFound.aspx"/>
</customErrors>
In this case, the Replace transform is used and
as you can see, it replaces the entire contents of the customErrors node.
The last example uses the Remove transform. I
find this useful in a number of scenarios, but the one I find most pertinent
for us is in the system.serviceModel section. Whenever you add a new service
reference to your application for a WCF or BizTalk hosted service, the wizard
will automatically generate a new binding definition for you, even if every
setting in it is identical to one you already have. In this case, I use the
Remove transform to eliminate all bindings that I don’t need as shown here:
Original setting:
<binding name="WSHttpBinding_ITwoWayAsync"
closeTimeout="00:01:00"
openTimeout="00:01:00"
receiveTimeout="00:10:00" sendTimeout="00:01:00"
...
</binding>
<binding name="WSHttpBinding_ITwoWayAsync1"
closeTimeout="00:01:00"
openTimeout="00:01:00"
receiveTimeout="00:10:00" sendTimeout="00:01:00"
...
</binding>
Transform:
<binding xdt:Locator="Condition(@name='WSHttpBinding_ITwoWayAsync1')"
xdt:Transform="Remove" />
Result:
<binding name="WSHttpBinding_ITwoWayAsync"
closeTimeout="00:01:00"
openTimeout="00:01:00"
receiveTimeout="00:10:00" sendTimeout="00:01:00"
...
</binding>
Note the use of the Locator attribute to specify
which element to remove. The locator attribute is scoped to the node
containing the transform, so the actual XPath expression that it resolves to
would be as follows:
configuration/.../wsHttpBinding/binding[@name='WSHttpBinding_ITwoWayAsync1']
In addition to the Locator attribute, there is
also a Match and an XPath attribute.
For full details on XML transform syntax and
futher examples, please refer to…
|