I have a WCF configuration file that I am trying to transform with SlowCheetah. For development use, we want to include the MEX endpoints, but when we release the product, these endpoints should be removed on all services except one. The server for which it should be left has the following endpoint:
<endpoint address="MEX"
binding="mexHttpBinding"
contract="IMetadataExchange" />
The ones that should be removed are as follows:
<endpoint address="net.tcp://computername:8001/WCFAttachmentService/MEX"
binding="netTcpBinding"
bindingConfiguration="UnsecureNetTcpBinding"
name="WCFAttachmentServiceMexEndpoint"
contract="IMetadataExchange" />
The transform I am using is:
<service>
<endpoint xdt:Locator="Condition(contains(@address, 'MEX') and not(contains(@binding, 'mexHttpBinding')))" xdt:Transform="RemoveAll" />
</service>
However, when I run this, ALL MEX endpoints are removed from the config file including the one that I wish to keep. How do I make this work properly?
The Locator
Condition expression that selects the nodes seems to be correct. If you had only the two endpoints you posted in your example, this expression will select the second endpoint.
According to the documentation the Transform
attribute RemoveAll
should "remove the selected element or elements ." Based on the information you posted it's not working as expected, since the first element was not selected and was removed anyway. Based on this StackOverflow answer it seems to me that the issue is with Condition
. I'm not sure if that's a bug (it's poorly documented), but you could try some alternative solutions:
1) Using XPath
instead of Condition
. The effective XPath expression that is applied to your configuration file as a result of the Condition
expression is:
/services/service/endpoint[contains(@address, 'MEX') and not(contains(@binding, 'mexHttpBinding'))]
You should also obtain the same result using the XPath
attribute instead of Condition
:
<endpoint xdt:Locator="XPath(/services/service/endpoint[contains(@address, 'MEX')
and not(contains(@binding, 'mexHttpBinding'))])" xdt:Transform="RemoveAll" />
2) Using Match
and testing an attribute such as binding
. This is a simpler test, and would be IMO the preferred way to perform the match. You could select the nodes you want to remove by the binding
attribute
<endpoint binding="netTcpBinding" xdt:Locator="Match(binding)" xdt:Transform="RemoveAll" />
3) Using XPath
instead of Match
in case you have many different bindings and only want to eliminate only those which are not mexHttpBinding
:
<endpoint xdt:Locator="XPath(/services/service/endpoint[not(@binding='mexHttpBinding'))" xdt:Transform="RemoveAll" />
4) Finally, you could try using several separate statements with Condition()
or Match()
to individually select the <endpoint>
elements you wish to remove, and use xdt:Transform="Remove"
instead of RemoveAll
.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.