2014-03-04 37 views
3

使用Visual Studio 2013 Premium。Web.Config转换:使用Insert()转换多个元素

目标:我在web.config中定义了多个WCF服务。为了保持web.config文件的可读性并使添加服务变得更简单,我想使用VS2013的XML转换为我的开发/生产环境的每个服务定义添加一些样板元素。

问题:我有多个<service>标记,但只有第一个转换正确。

这里是我的web.config的简化版本有两个服务来定义:

<?xml version="1.0" encoding="utf-8"?> 
<configuration> 
    <system.serviceModel> 
    <services> 
     <service name="AppName.AccountManagerService"> 
     <endpoint address="AccountManagerService" binding="netTcpBinding" 
      bindingConfiguration="" contract="Shared.Contracts.IAccountManagerService" /> 
     </service> 
     <service name="AppName.TicketManagerService"> 
     <endpoint address="TicketManagerService" binding="netTcpBinding" 
      bindingConfiguration="" contract="Shared.Contracts.ITicketManagerService" /> 
     </service> 
    </services> 
</configuration> 

我想创建一个元数据交换终结,并做一些其他的事情(未显示),以每<service>标签。

这里仅显示元数据交换终结点的简化Web.Debug.Config:我得到这个

<?xml version="1.0" encoding="utf-8"?> 
<configuration xmlns:xdt="http://schemas.microsoft.com/XML-Document-Transform"> 
    <system.serviceModel> 
    <services> 
     <service xdt:Locator="XPath(/configuration/system.serviceModel/services/service)"> 
     <endpoint kind="mexEndpoint" 
        address="mex" 
        xdt:Transform="Insert()" 
       /> 
     </service> 
    </services> 
    </system.serviceModel> 
</configuration> 

<?xml version="1.0" encoding="utf-8"?> 
<configuration> 
    <system.serviceModel> 
    <services> 
     <service name="AppName.AccountManagerService"> 
     <endpoint address="AccountManagerService" binding="netTcpBinding" 
      bindingConfiguration="" contract="Shared.Contracts.IAccountManagerService" /> 

     <!-- Yay! --> 
     <endpoint kind="mexEndpoint" 
        address="mex" 
       /> 

     </service> 
     <service name="AppName.TicketManagerService"> 
     <endpoint address="TicketManagerService" binding="netTcpBinding" 
      bindingConfiguration="" contract="Shared.Contracts.ITicketManagerService" /> 

     <!-- Hey, where's the endpoint tag for this one? --> 

     </service> 
    </services> 
</configuration> 

我试过在xdt:Locator属性上XPath争论这些变化的:

1. /configuration/system.serviceModel/services/service 
2. /configuration/system.serviceModel/services//service 
3. //service 

所有的w hich变形只有第一个<service>部分。

我试过把xdt:Locator属性放在<endpoint>标签等等上都无济于事。

我有多个XPath可视化工具和工具,它们全部匹配<service>标记与上面的XPath#1一起使用。此外,此错误发生在“预览变换”和Web部署工具预览中。

我在做什么错? (我的解决方法,在这一点上,是在我的原始Web.Config中包含Mex端点和其余调试信息,然后使用“RemoveAll()”将其删除,但这使得我的Web.Config真的很混乱,难以阅读。)

回答

1

我最近遇到了这个问题,事实证明它不被支持。

我的工作是添加一个自定义转换,并使用它来代替Insert。与他们的实现问题是默认的插入仅修改第一个值(即使XPath表达式检索列表)。

的XDT源可以在这里找到:http://xdt.codeplex.com/

我对面跑让我在正确的方向上的文章:http://blog.appharbor.com/2012/07/27/custom-web-config-transforms-and-merges

我所做的就是添加一个新的类其来源,并能实现你正在寻找的东西。

internal class InsertMultiple : Transform 
{ 
    public InsertMultiple() 
    { 
     //this is the line that allows it to apply the transform for all nodes 
     //that were located with your XPath expression. 
     ApplyTransformToAllTargetNodes = true; 
    } 

    protected override void Apply() 
    { 
     CommonErrors.ExpectNoArguments(Log, TransformNameShort, ArgumentString); 

     TargetNode.AppendChild(TransformNode); 

     Log.LogMessage(MessageType.Verbose, SR.XMLTRANSFORMATION_TransformMessageInsert, TransformNode.Name); 
    } 
}