简体   繁体   中英

SlowCheetah transform ignores multiple conditions

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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM