Условие локатора преобразования Web.config или xpath не работают с несколькими атрибутами
Я использую библиотеку Microsoft XDT для преобразования моих файлов web.config и обнаружил, что Locator не работает должным образом. Используя приведенный ниже пример, я ожидаю, что оба атрибута установлены, и узел преобразователя вставлен во все три приложения, но только атрибуты обновлены во всех трех. Узел конвертера вставляется только в первый аппендер. Как заставить его вставлять все три узла приложения log4net?
Я попытался перейти на XPath, но он только выдает ошибки. Рабочий пример был бы хорош, потому что каждый пример, которому я следовал до сих пор, кажется, терпит неудачу с ошибкой.
Тестовый сайт: https://webconfigtransformationtester.apphb.com/
Например:
Web.config
<?xml version="1.0"?>
<configuration>
<log4net>
<appender name="App1">
<layout>
<conversionPattern value="foo"/>
</layout>
</appender>
<appender name="App2">
<layout>
<conversionPattern value="foo"/>
</layout>
</appender>
<appender name="App3">
<layout>
<conversionPattern value="foo"/>
</layout>
</appender>
</log4net>
</configuration>
Web.Debug.config
<?xml version="1.0"?>
<configuration xmlns:xdt="http://schemas.microsoft.com/XML-Document-Transform">
<log4net>
<appender xdt:Locator="Condition(@name='App1' or @name='App2' or @name='App3')">
<layout>
<conversionPattern value="bar" xdt:Transform="SetAttributes" />
<converter xdt:Transform="Insert">
<name value="Default" />
<type value="Common.DefaultConverter, Common" />
</converter>
</layout>
</appender>
</log4net>
</configuration>
Результаты:
<?xml version="1.0"?>
<configuration>
<log4net>
<appender name="App1">
<layout>
<conversionPattern value="bar" />
<converter><name value="Default" /><type value="Common.DefaultConverter, Common" /></converter></layout>
</appender>
<appender name="App2">
<layout>
<conversionPattern value="bar" />
</layout>
</appender>
<appender name="App3">
<layout>
<conversionPattern value="bar" />
</layout>
</appender>
</log4net>
</configuration>
1 ответ
Оказывается, это было разработано таким образом. Только атрибуты применяются ко всем целевым узлам. Чтобы обойти проблему, загрузите код отсюда и добавьте следующие строки:
В XmlElementContext добавьте свойство:
internal bool HasLocator
{
get
{
return this.LocatorAttribute != null || (this.parentContext != null && this.parentContext.HasLocator);
}
}
В XmlTransform измените эту строку, добавив вызов HasLocator:
if (ApplyTransformToAllTargetNodes || context.HasLocator) {
Этот код определит, был ли установлен "Локатор" в текущем контексте или в каком-либо родительском контексте (как в моем примере), и применяет все преобразования ко всем целевым узлам.