我有一个web.config文件,我需要在其中插入<configSections />
元素或操作该节点的子节点(如果已经存在)。
如果它已经存在,我不想再次插入它(显然,因为它只允许存在一次)。
通常,这不是问题,但是:
Source: MSDN。
因此,如果我使用xdt:Transform="InsertIfMissing"
,那么<configSections />
元素将始终插入到任何现有的子元素之后(并且总是有一些),这违反了上述限制,即它必须是<configuration />
的第一个子元素
我尝试通过以下方式进行这项工作:
<configSections
xdt:Transform="InsertBefore(/configuration/*[1])"
xdt:Locator="Condition(not(.))" />
如果
<configSections />
元素尚不存在,则可以完美工作。但是,我指定的条件似乎被忽略了。实际上,我已经尝试了一些条件,例如:
Condition(not(/configuration[configSections]))
Condition(/configuration[configSections] = false())
Condition(not(/configuration/configSections))
Condition(/configuration/configSections = false())
最后,出于绝望,我尝试了:
Condition(true() = false())
它仍然插入了
<configSections />
元素。重要的是要注意,我正在尝试将其包含在NuGet包中,因此我将无法使用自定义转换(like the one AppHarbor uses)。
只有在元素不存在的情况下,还有其他巧妙的方法可以将元素放置在正确的位置吗?
要测试这一点,请使用AppHarbors config transform tester。将Web.config替换为以下内容:
<?xml version="1.0"?>
<configuration>
<configSections>
<section name="initialSection" />
</configSections>
</configuration>
和Web.Debug.config具有以下内容:
<?xml version="1.0"?>
<configuration xmlns:xdt="http://schemas.microsoft.com/XML-Document-Transform">
<configSections
xdt:Transform="InsertBefore(/configuration/*[1])"
xdt:Locator="Condition(true() = false())" />
<configSections>
<section name="mySection" xdt:Transform="Insert" />
</configSections>
</configuration>
结果将显示两个
<configSections />
元素,其中一个包含“mySection”,第一个,如InsertBefore转换中所指定。为什么未考虑“定位器条件”?
最佳答案
因此,面对相同的问题后,我想出了一个解决方案。它既不漂亮也不优雅,但是可以工作。 (至少在我的机器上)
我只是将逻辑分为3个不同的语句。首先,我在正确的位置(首先)添加一个空的configSections。然后,我将新配置插入的最后 configSections中,如果它是唯一的,则为新配置,否则为先前存在的配置。
最后,我删除了可能存在的任何空configSections元素。我无缘无故使用RemoveAll,您可能应该使用Remove。
总体代码如下所示:
<configSections xdt:Transform="InsertBefore(/configuration/*[1])" />
<configSections xdt:Locator="XPath(/configuration/configSections[last()])">
<section name="initialSection" xdt:Locator="Match(name)" xdt:Transform="InsertIfMissing" />
</configSections>
<configSections xdt:Transform="RemoveAll" xdt:Locator="Condition(count(*)=0)" />
仍然悬而未决的问题是,为什么InsertBefore不考虑定位器条件。还是为什么我不能处理InsertBefore的空匹配集,因为那会让我做一些有趣的事情,例如
//configuration/*[position()=1 and not(local-name()='configSections')]
老实说,这是我要实现的目标的一种更清晰的方法。
关于web-config - XDT转换:InsertBefore-定位条件被忽略,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/18737022/