2014-03-04 59 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); 
    } 
}