Web.config 转换定位器条件或 xpath 不适用于多个属性

Web.config transformation locator condition or xpath not working with multiple attributes

我正在使用 Microsoft 的 XDT 库转换我的 web.config 文件,发现 Locator 没有按预期工作。使用下面的示例,我希望两个属性都已设置并且转换器节点已插入到所有三个附加程序中,但只有属性在所有三个附加程序中都被更新。转换器节点仅插入到第一个附加程序中。我如何让它插入所有三个 log4net appender 节点?

我试过切换到 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>

原来是这么设计的。只有属性适用于所有目标节点。要解决此问题,请从 here 下载代码并添加以下行:

在 XmlElementContext 中,添加 属性:

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

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

if (ApplyTransformToAllTargetNodes || context.HasLocator) {

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