Условие локатора преобразования 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) {

Этот код определит, был ли установлен "Локатор" в текущем контексте или в каком-либо родительском контексте (как в моем примере), и применяет все преобразования ко всем целевым узлам.

Другие вопросы по тегам