【问题标题】:Web Config Transforms: Insert If Not ExistsWeb Config 转换:如果不存在则插入
【发布时间】:2013-02-12 17:07:41
【问题描述】:

当且仅当匹配的元素在目标中存在时,我想应用转换。使用 http://webconfigtransformationtester.apphb.com/ 尝试各种 xpath 表达式,但到目前为止没有运气。

例如如果目标 web.config 看起来像这样:

<configuration>
  <system.web>
    <compilation debug="true" />
  </system.web>
</configuration>

那么输出应该是这样的:

<configuration>
  <connectionStrings>
    <add name="MyCs" provider="System.Data.SqlClient" connectionString="" />
    <add name="SomeOtherCs" provider="System.Data.SqlClient" connectionString="" />
  </connectionStrings>
  <system.web>
    <compilation debug="true" />
  </system.web>
</configuration>

但是如果目标看起来像这样:

<configuration>
  <connectionStrings>
    <add name="MyCs" provider="System.Data.IChangedIt" connectionString="my connection string here" />
  </connectionStrings>
  <system.web>
    <compilation debug="true" />
  </system.web>
</configuration>

那么转换的结果应该是这样的:

<configuration>
  <connectionStrings>
    <add name="MyCs" provider="System.Data.IChangedIt" connectionString="my connection string here" />
    <add name="SomeOtherCs" provider="System.Data.SqlClient" connectionString="" />   
  </connectionStrings>
  <system.web>
    <compilation debug="true" />
  </system.web>
</configuration>

换句话说,我只是想将命名的连接字符串添加到配置中,但让管理员用他自己的值填写它。我认为它会像 xdt:Transform="Insert" xdt:Locator="XPath(count(/configuration/connectionStrings)=0)" 一样简单(如果不存在则添加一个 cs 配置部分)但显然不是。

【问题讨论】:

标签: xpath web-config web-config-transform


【解决方案1】:

在 VS2012 中使用 xdt:Transform="InsertIfMissing"XmlTransform 任务。微软似乎还没有更新他们的文档来反映这一点。

【讨论】:

    【解决方案2】:

    在我的情况下,xdt:Transform="InsertIfMissing" 没有xdt:Locator="Match(name)" 就无法工作

    【讨论】:

    • 可能只在叶子节点上才需要
    • 这正是我所需要的。我试图为特定路径插入 location 标签,但是原始 web.config 已经有一些 location 标签用于其他路径。所以我只需要添加一个xdt:Locator="Match(path) 标签。我知道这看起来很奇怪,但就我而言,我不能让这个特定位置出现在原始配置中,只有在发布到服务器时。
    • 这正是我所需要的——添加键但如果它们存在就不要修改。我需要变换、定位器和值。这是VS2015
    • +1 这是关键,在我的设置中,我的 xdt:Locator="Match(key)" 任何人都可以复制粘贴而看不到要“替换”的内容。 VS2017 适合我。
    【解决方案3】:

    xdt:Transform="InsertIfMissing" 尝试这种替代转换:

    <?xml version="1.0"?>
    <configuration xmlns:xdt="http://schemas.microsoft.com/XML-Document-Transform">
      <nodeToInsertIfMissing xdt:Transform="Insert" />
      <nodeToInsertIfMissing xdt:Transform="Remove" xdt:Locator="XPath(/configuration/nodeToInsertIfMissing[2])" />
    </configuration>
    

    它应该在MSDN documentation 之后工作:

    插入 - 将转换文件中定义的元素添加为选定元素的同级元素。新元素添加到任何集合的末尾

    所以,如果节点已经存在,我们添加第二个,然后删除这个节点(第二个)。否则,我们添加新的唯一节点,但删除操作将失败。

    注意:它似乎不适用于 NuGet *.(un)install.xdt 转换。 InsertIfMissing

    【讨论】:

      【解决方案4】:

      确认在 VS2015 和包管理器控制台主机版本 3.4.4.1321 中工作(您可以在打开包管理器控制台时找到它)。

      如果 'configuration\connectionStrings\add\@name' 不存在,这将插入。

      app.config.install.xdt:

      <?xml version="1.0" encoding="utf-8" ?>
      <configuration xmlns:xdt="http://schemas.microsoft.com/XML-Document-Transform">
          <connectionStrings xdt:Transform="InsertIfMissing">
              <add name="MyCs" provider="System.Data.SqlClient" connectionString="" xdt:Transform="InsertIfMissing" xdt:Locator="Match(name)"/>
          </connectionStrings>
      </configuration>
      

      .nuspec 文件:

      <files>
          <file src="app.config.install.xdt" target="content\app.config.install.xdt" />
      

      【讨论】:

      • 可能值得注意 - 我发现如果 app.config 中还没有 connectionStrings 元素,这将失败,您也可以添加 xdt:Transform="InsertIfMissing" 以涵盖这一点案例。
      【解决方案5】:

      使用xdt:Transform="Remove" 后跟xdt:Transform="Insert" 转换。在别处建议的 xdt:Transform="InsertIfMissing" 对我不起作用,看起来像是特定于它的版本。

      【讨论】:

      • 我们仍然在 2010 年,所以这对我们来说非常有效!
      • 这在 VS 2012 中就像一个魅力。接受的答案中建议的方法引发了异常!!
      猜你喜欢
      • 2013-08-06
      • 2018-09-17
      • 2014-06-11
      • 1970-01-01
      • 2017-04-24
      • 1970-01-01
      • 2016-05-15
      • 1970-01-01
      • 2015-03-31
      相关资源
      最近更新 更多