2012-01-24 58 views
41

Có thể sử dụng chuyển đổi tài liệu XML của Microsoft, để chuẩn bị web.configs, bên ngoài MSBuild không? Tôi muốn sử dụng PowerShell để thực hiện các phép biến đổi này mà không cần phải chạy điều này thông qua công cụ MSBuild. Nếu Microsoft đã sử dụng XSLT chuẩn thì nó sẽ dễ dàng thực hiện trong PowerShell. Từ những gì tôi có thể nói tôi phải sử dụng C: \ Program Files của họ (x86) \ MSBuild \ Microsoft \ VisualStudio \ v10.0 \ Web \ Microsoft.Web.Publishing.Tasks.dll mà đòi hỏi một công cụ xây dựng. Cảm ơnWeb.Config chuyển đổi bên ngoài Microsoft MSBuild?

Trả lời

77

Tôi đã tạo một hàm nhỏ để xử lý Chuyển đổi tài liệu XML của Microsoft trong PowerShell.

Tôi đã sao chép tệp Microsoft.Web.XmlTransform.dll từ thư viện xây dựng Visual Studio sang đường dẫn tập lệnh của tôi, nhưng bạn có thể tham khảo nó từ thư mục nguồn nếu bạn muốn.

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); 
} 

Để chuyển đổi web.config sử dụng web.release.config:

XmlDocTransform("Web.config", "Web.Release.config") 
+0

Tuyệt vời, đó chính xác là những gì tôi cần để viết một phiên bản C# –

+10

Tôi có một kịch bản PowerShell tự khởi động mà bạn có thể sử dụng tại https://gist.github.com/sayedihashimi/f1fdc4bfba74d398ec5b –

+1

rất đẹp! Tôi đã phải gọi Resolve-Path trên $ xml và $ xdt nhưng ngoài ra, nó rất hữu ích !, thx – PierrOz

10

Logic của phép biến đổi được chứa bên trong nhiệm vụ TransformXml. Nếu bạn muốn gọi nó từ mã, bạn sẽ phải sử dụng MSBuild API với một công cụ giả lập và thực thi nó. Tôi có một số mã cho điều này nếu bạn muốn.

Trong trường hợp của bạn vì bạn đã đề cập PowerShell, điều tốt nhất để bạn làm là chỉ cần tạo một tệp MSBuild bao bọc để gọi tác vụ TransformXml. Tôi nói điều này bởi vì PowerShell được cấu hình để chạy dưới .NET 2.0, nhưng nhiệm vụ TransformXml yêu cầu .NET 4.0. Để gọi nó từ một tập tin MSBuild giả, bạn có thể kiểm tra blog của tôi tại http://sedodream.com/2010/04/26/ConfigTransformationsOutsideOfWebAppBuilds.aspx, nhưng tôi cũng đã dán một mẫu từ liên kết dưới đây.

<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> 
+2

Cảm ơn Sayed, tôi thực sự đã đi với giải pháp của bạn. Tôi đã sửa đổi nó một chút để bao gồm các nhóm thuộc tính cho 3 mục, vì vậy tôi có thể ghi đè lên các nhóm trên dòng lệnh từ PowerShell. Biết rằng từ cuốn sách của bạn :) ' Web.config Web.Debug.config Web.Prod.config \t \t \t \t ' –

4

Hãy xem xét sử dụng MSDeploy vì nó có API kịch bản PowerShell cho phép bạn chuyển đổi và triển khai gói của mình.

Bạn cũng có thể xem XML-Document-Transform nếu bạn muốn bạn có thể viết mã của riêng bạn để thực hiện Chuyển đổi.

Đây là dự án codeplex đã thực hiện tương tự. XDT Transformation Tool

5

Dựa trên câu trả lời Michel của tôi đã viết một hàm C# mà sẽ thực hiện như nhau.

Tất nhiên bạn có thể gọi DLL kết quả với PowerShell, nhưng tôi đã thực sự tìm kiếm một phiên bản đầy đủ programatic, vì vậy ở đây nó là, trong trường hợp bất cứ ai đang tìm kiếm giải pháp tương tự:

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); 
} 

Bạn sẽ chỉ cần đề cập tới sau:

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

+0

Câu trả lời hay, điều này cần nhiều phiếu bầu hơn! – Matt

5

Microsoft đã đăng XDT lên codeplex http://xdt.codeplex.com và làm gói NuGet https://www.nuget.org/packages/Microsoft.Web.Xdt/. Tôi cũng đã tạo ra một con lợn NuGet với một nhiệm vụ MSBuild, TransformXml và một .exe để gọi chúng https://www.nuget.org/packages/SlowCheetah.Xdt/1.1.6-beta.

Đối với PowerShell, tôi đã tạo tập lệnh tự khởi động mà bạn có thể sử dụng https://gist.github.com/sayedihashimi/f1fdc4bfba74d398ec5b.

Tìm hiểu thêm về kịch bản tự khởi động tại http://sedodream.com/2014/07/22/StopCheckinginBinariesInsteadCreateSelfbootstrappingScripts.aspx.

1

Tôi đã cập nhật tập lệnh một chút để nó hoạt động với phiên bản PowerShell mới nhất và làm cho nó dễ dàng hơn một chút.

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 
    } 

Và để gọi chức năng sử dụng

XmlDocTransform "App.config" "App.acc.config" 
Các vấn đề liên quan