0

I'm using Microsoft's XDT library to transform my web.config files and discovered that Locator is not working as expected. Using the example below, I would expect that both the attributes are set and the converter node is inserted in all three appenders, but only the attributes are updated in all three. The converter node is only inserted into the first appender. How do I get it to insert into all three log4net appender nodes?

I've tried switching to XPath, but it only throws errors. A working example would be nice, because every example I've followed so far seems to fail with an error.

Test site: https://webconfigtransformationtester.apphb.com/

For example:

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>

Results:

<?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>
4

1 回答 1

0

事实证明,它是这样设计的。只有属性应用于所有目标节点。要解决此问题,请从此处下载代码并添加以下行:

在 XmlElementContext 中,添加属性:

   internal bool HasLocator
    {
        get
        {
            return this.LocatorAttribute != null || (this.parentContext != null && this.parentContext.HasLocator);
        }
    }

在 XmlTransform 中修改这一行,添加对 HasLocator 的调用:

if (ApplyTransformToAllTargetNodes || context.HasLocator) {

此代码将确定是否在当前上下文或任何父上下文(如我的示例中)中设置了“定位器”,并将所有转换应用于所有目标节点。

于 2015-10-26T15:23:40.037 回答