Web.Config transforma fuera de Microsoft MSBuild?


¿Es posible utilizar la transformación de documentos XML de Microsoft para preparar la web?configs, fuera de MSBuild? Me gustaría usar PowerShell para hacer estas transformaciones sin tener que ejecutar esto a través del motor de MSBuild. Si Microsoft hubiera utilizado XSLT estándar, sería fácil hacerlo en PowerShell. Por lo que puedo decir que tengo que usar su C:\Program Files (x86)\MSBuild\Microsoft\VisualStudio\v10.0\Web \ Microsoft.Web.Publicar.Tarea.dll que requiere un motor de compilación. Gracias

Author: Jason, 2012-01-24

6 answers

He creado una pequeña función para gestionar la transformación de documentos XML de Microsoft en PowerShell.

Copié el Microsoft.Web.XmlTransform.archivo dll de la carpeta de compilación de Visual Studio a la ruta de mi script, pero puede hacer referencia desde la carpeta de origen si lo desea.

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

Para transformar web.config usando web.lanzar.config:

XmlDocTransform("Web.config", "Web.Release.config")
 87
Author: Mike DaCosta,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2013-05-28 18:00:33

La lógica de la transformación está contenida dentro de la tarea TransformXml. Si desea llamarlo desde código, tendría que usar la API de MSBuild con un motor de simulación y ejecutarlo. Tengo un código para esto si quieres.

En su caso, ya que mencionó PowerShell, lo mejor que puede hacer es crear un archivo MSBuild de envoltura para invocar la tarea TransformXml. Digo esto porque PowerShell está configurado para ejecutarse en. NET 2.0, pero la tarea TransformXml requiere . NET 4.0. Para llamarlo desde un archivo MSBuild ficticio, puede consultar mi blog en http://sedodream.com/2010/04/26/ConfigTransformationsOutsideOfWebAppBuilds.aspx , pero también he pegado una muestra de ese enlace a continuación.

<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>
 11
Author: Sayed Ibrahim Hashimi,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2012-01-24 17:08:38

Basado en la respuesta de Michel escribí una función de C# que logrará lo mismo.

Por supuesto, podría invocar el DLL resultante con PowerShell, pero en realidad estaba buscando una versión completamente programática, así que aquí está, en caso de que alguien más esté buscando una solución similar:

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

Solo tendrá que incluir una referencia a lo siguiente:

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

 8
Author: Sebastian K,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2014-02-02 23:18:15

Microsoft ha publicado XDT en codeplex http://xdt.codeplex.com y como paquete NuGet https://www.nuget.org/packages/Microsoft.Web.Xdt / . También he creado un NuGet pig con una tarea de MSBuild, TransformXml, y an.exe para invocarlos https://www.nuget.org/packages/SlowCheetah.Xdt/1.1.6-beta .

Para PowerShell he creado un script de autoarranque que puedes usar https://gist.github.com/sayedihashimi/f1fdc4bfba74d398ec5b .

Más acerca de auto bootstrapping scripts en http://sedodream.com/2014/07/22/StopCheckinginBinariesInsteadCreateSelfbootstrappingScripts.aspx.

 7
Author: Sayed Ibrahim Hashimi,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2014-07-25 08:17:44

Eche un vistazo al uso de MSDeploy, ya que tiene API de scripting de PowerShell que le permiten transformar e implementar su paquete.

También puede ver XML-Document-Transform que si lo desea puede escribir su propio código para realizar la Transformación.

Aquí hay un proyecto de codeplex que hizo algo similar.Herramienta de transformación XDT

 4
Author: SoftwareCarpenter,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2012-01-24 17:15:42

He actualizado un poco el script para que funcione con la última versión de powershell y que sea un poco más fácil.

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
  }

Y para invocar la función use

 XmlDocTransform "App.config" "App.acc.config"
 4
Author: c_wiz_kid,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2016-10-11 06:40:20