Трансформация SlowCheetah игнорирует несколько условий
У меня есть файл конфигурации WCF, который я пытаюсь преобразовать с помощью SlowCheetah. Для разработки мы хотим включить конечные точки MEX, но когда мы выпускаем продукт, эти конечные точки должны быть удалены во всех службах, кроме одной. Сервер, для которого он должен быть оставлен, имеет следующую конечную точку:
<endpoint address="MEX"
binding="mexHttpBinding"
contract="IMetadataExchange" />
Те, которые должны быть удалены:
<endpoint address="net.tcp://computername:8001/WCFAttachmentService/MEX"
binding="netTcpBinding"
bindingConfiguration="UnsecureNetTcpBinding"
name="WCFAttachmentServiceMexEndpoint"
contract="IMetadataExchange" />
Я использую преобразование:
<service>
<endpoint xdt:Locator="Condition(contains(@address, 'MEX') and not(contains(@binding, 'mexHttpBinding')))" xdt:Transform="RemoveAll" />
</service>
Однако, когда я запускаю это, ВСЕ конечные точки MEX удаляются из файла конфигурации, включая тот, который я хочу сохранить. Как мне сделать это правильно?
1 ответ
Locator
Выражениеусловия, которое выбирает узлы, кажется правильным. Если у вас было только две конечные точки, которые вы разместили в своем примере, это выражение выберет вторую конечную точку.
Согласно документации Transform
атрибут RemoveAll
должен "удалить выбранный элемент или элементы." Судя по размещенной вами информации, она не работает должным образом, поскольку первый элемент не был выбран и все равно был удален. На основании этого ответа Stackru мне кажется, что проблема с Condition
, Я не уверен, что это ошибка (она плохо документирована), но вы можете попробовать некоторые альтернативные решения:
1) Использование XPath
вместо Condition
, Эффективное выражение XPath, которое применяется к вашему файлу конфигурации в результате Condition
Выражение
/services/service/endpoint[contains(@address, 'MEX') and not(contains(@binding, 'mexHttpBinding'))]
Вы также должны получить тот же результат, используя XPath
атрибут вместо Condition
:
<endpoint xdt:Locator="XPath(/services/service/endpoint[contains(@address, 'MEX')
and not(contains(@binding, 'mexHttpBinding'))])" xdt:Transform="RemoveAll" />
2) Использование Match
и тестирование атрибута, такого как binding
, Это более простой тест, и IMO будет предпочтительным способом выполнения сопоставления. Вы можете выбрать узлы, которые вы хотите удалить с помощью binding
атрибут
<endpoint binding="netTcpBinding" xdt:Locator="Match(binding)" xdt:Transform="RemoveAll" />
3) ИспользованиеXPath
вместо Match
если у вас много разных привязок и вы хотите удалить только те, которые не mexHttpBinding
:
<endpoint xdt:Locator="XPath(/services/service/endpoint[not(@binding='mexHttpBinding'))" xdt:Transform="RemoveAll" />
4) Наконец, вы можете попробовать использовать несколько отдельных операторов с Condition()
или же Match()
индивидуально выбрать <endpoint>
элементы, которые вы хотите удалить, и использовать xdt:Transform="Remove"
вместо RemoveAll
,