Web.Config在Microsoft MSBuild之外转换?

问题描述 投票:51回答:7

是否可以使用Microsoft的XML文档转换,在MSBuild之外准备web.configs?我想使用PowerShell进行这些转换,而无需通过MSBuild引擎运行它。如果Microsoft使用标准XSLT,那么在PowerShell中很容易做到。据我所知,我必须使用他们需要构建引擎的C:\ Program Files(x86)\ MSBuild \ Microsoft \ VisualStudio \ v10.0 \ Web \ Microsoft.Web.Publishing.Tasks.dll。谢谢

powershell msbuild powershell-v2.0 xml-document-transform
7个回答
98
投票

我创建了一个小函数来处理PowerShell中的Microsoft XML文档转换。

我将Microsoft.Web.XmlTransform.dll文件从Visual Studio构建文件夹复制到我的脚本路径,但如果您愿意,可以从源文件夹中引用它。

function XmlDocTransform($xml, $xdt)
{
    if (!$xml -or !(Test-Path -path $xml -PathType Leaf)) {
        throw "File not found. $xml";
    }
    if (!$xdt -or !(Test-Path -path $xdt -PathType Leaf)) {
        throw "File not found. $xdt";
    }

    $scriptPath = (Get-Variable MyInvocation -Scope 1).Value.InvocationName | split-path -parent
    Add-Type -LiteralPath "$scriptPath\Microsoft.Web.XmlTransform.dll"

    $xmldoc = New-Object Microsoft.Web.XmlTransform.XmlTransformableDocument;
    $xmldoc.PreserveWhitespace = $true
    $xmldoc.Load($xml);

    $transf = New-Object Microsoft.Web.XmlTransform.XmlTransformation($xdt);
    if ($transf.Apply($xmldoc) -eq $false)
    {
        throw "Transformation failed."
    }
    $xmldoc.Save($xml);
}

使用web.release.config转换web.config:

XmlDocTransform -xml "Web.config" -xdt "Web.Release.config"

或者,您可以使用Sayed的自引导Xml转换脚本,它将负责为您获取Microsoft.Xml.Xdt.dll:

https://gist.github.com/sayedihashimi/f1fdc4bfba74d398ec5b


12
投票

转换的逻辑包含在TransformXml任务本身内部。如果要从代码中调用它,则必须使用带有模拟引擎的MSBuild API并执行它。如果你愿意,我有一些代码。

在你提到PowerShell的情况下,你要做的最好的事情就是创建一个包装器MSBuild文件来调用TransformXml任务。我这样说是因为PowerShell配置为在.NET 2.0下运行,但TransformXml任务需要.NET 4.0。为了从虚拟MSBuild文件中调用它,您可以在http://sedodream.com/2010/04/26/ConfigTransformationsOutsideOfWebAppBuilds.aspx上查看我的博客,但我也粘贴了下面该链接的示例。

<Project ToolsVersion="4.0" DefaultTargets="Demo" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
    <UsingTask TaskName="TransformXml"
             AssemblyFile="$(MSBuildExtensionsPath)\Microsoft\VisualStudio\v10.0\Web\Microsoft.Web.Publishing.Tasks.dll"/>

    <Target Name="Demo">
        <TransformXml Source="app.config"
                      Transform="Transform.xml"
                      Destination="app.prod.config"/>
    </Target>
</Project>

10
投票

微软已将XDT发布到codeplex http://xdt.codeplex.com和作为NuGet包https://www.nuget.org/packages/Microsoft.Web.Xdt/。我还创建了一个带有MSBuild任务的NuGet pig,TransformXml和一个.exe来调用它们https://www.nuget.org/packages/SlowCheetah.Xdt/1.1.6-beta

对于PowerShell,我创建了一个自引导脚本,您可以使用https://gist.github.com/sayedihashimi/f1fdc4bfba74d398ec5b

有关http://sedodream.com/2014/07/22/StopCheckinginBinariesInsteadCreateSelfbootstrappingScripts.aspx的自引导脚本的更多信息。


9
投票

根据Michel的回答,我写了一个C#函数,它将完成相同的工作。

当然你可以使用PowerShell调用生成的DLL,但我实际上是在寻找一个完全编程的版本,所以在这里,以防其他人正在寻找类似的解决方案:

using Microsoft.Web.XmlTransform;

...

public static void TransformConfig(string configFileName, string transformFileName)
{
     var document = new XmlTransformableDocument();
     document.PreserveWhitespace = true;
     document.Load(configFileName);

     var transformation = new XmlTransformation(transformFileName);
     if (!transformation.Apply(document))
     {
         throw new Exception("Transformation Failed");
     }
     document.Save(configFileName);
}

您只需要包含以下参考:

C:\ Program Files(x86)\ MSBuild \ Microsoft \ VisualStudio \ v11.0 \ Web \ Microsoft.Web.XmlTransform.dll


6
投票

我稍微更新了脚本以使其与最新版本的PowerShell一起使用并使其更容易一些。

function XmlDocTransform($xml, $xdt)
{
      $scriptpath = $PSScriptRoot + "\"
      $xmlpath = $scriptpath + $xml
      $xdtpath = $scriptpath + $xdt

      if (!($xmlpath) -or !(Test-Path -path ($xmlpath) -PathType Leaf)) {
         throw "Base file not found. $xmlpath";
      }

      if (!($xdtpath) -or !(Test-Path -path ($xdtpath) -PathType Leaf)) {
         throw "Transform file not found. $xdtpath";
      }

      Add-Type -LiteralPath "$PSScriptRoot\Microsoft.Web.XmlTransform.dll"

      $xmldoc = New-Object   Microsoft.Web.XmlTransform.XmlTransformableDocument;
      $xmldoc.PreserveWhitespace = $true
      $xmldoc.Load($xmlpath);

      $transf = New-Object Microsoft.Web.XmlTransform.XmlTransformation($xdtpath);
      if ($transf.Apply($xmldoc) -eq $false)
      {
          throw "Transformation failed."
      }
      $xmldoc.Save($xmlpath);

      Write-Host "Transformation succeeded" -ForegroundColor Green
  }

并调用函数使用

 XmlDocTransform "App.config" "App.acc.config"

5
投票

看一下使用MSDeploy,因为它有PowerShell脚本API,允许您转换和部署您的包。

您还可以查看XML-Document-Transform,如果您愿意,可以编写自己的代码来执行Transform。

这是一个类似的项目,做了类似的事情.XDT Transformation Tool


0
投票

因此递归地略微扩展到工作

    function XmlDocTransform($xml, $xdt)
    {
        if (!$xml -or !(Test-Path -path $xml -PathType Leaf)) {
            throw "File not found. $xml";
        }
        if (!$xdt -or !(Test-Path -path $xdt -PathType Leaf)) {
            throw "File not found. $xdt";
        }
        $scriptPath = (Get-Variable MyInvocation -Scope 1).Value.InvocationName | split-path -parent
        Add-Type -LiteralPath "$scriptPath\Microsoft.Web.XmlTransform.dll"
        $xmldoc = New-Object Microsoft.Web.XmlTransform.XmlTransformableDocument;
        $xmldoc.PreserveWhitespace = $true
        $xmldoc.Load($xml);
        $transf = New-Object Microsoft.Web.XmlTransform.XmlTransformation($xdt);
        if ($transf.Apply($xmldoc) -eq $false)
        {
            throw "Transformation failed."
        }
        $xmldoc.Save($xml);
    }
    function DoConfigTransform($webFolder, $environment)
    {
        $allConfigFiles = Get-ChildItem $webFolder -File -Filter *.config -Recurse
          $transformFiles = $allConfigFiles | Where-Object {$_.Name -like ("*." + $environment + ".config")} | %{$_.fullname}
          ForEach($item in $transformFiles)
          {
            $origFile = $item -replace("$environment.",'')
              XmlDocTransform -xml $origFile -xdt $origFile$item
              #Write-Output ("orig = " + $origFile + ", transform = " + $item)
          }
          cd C:\WebApplications\xxx\xxx\xxx\
          .\PostDeploy.ps1
    }
    DoConfigTransform -webFolder "C:\WebApplications\xxx\xxx\xxx" -environment "xx-xxx-xx"

所以DoConfigTransform逻辑变为:

  • 以递归方式查找所有配置文件
  • 查找我们作为参数#passsed的环境的所有转换模板
  • 对于每个转换文件,找到相应的配置
  • 然后做转换
  • 代码运行postdeploy脚本以删除所有不需要的转换文件。
© www.soinside.com 2019 - 2024. All rights reserved.