2011-03-09 26 views
8

Estoy buscando mejor forma para parchar un archivo XML (en realidad, app.config). Más específicamente, necesito agregar algo a la sección <appConfig> (que podría no existir), así como a varios elementos <bindingRedirect> para hacer coincidir las entradas.Modificación de un XML a través de la línea de comandos

También necesito esto como una herramienta de línea de comandos, para una implementación más sencilla.

pensé en resolver esto de varias maneras:

  1. Una aplicación de consola ad-hoc para parchear el archivo con LINQ to XML - más fácil
  2. mediante XSLT - guardar una copia del XML modificado, más adelante reemplazando el original (a menos que sea posible transformar el XML de origen en el lugar?)
  3. Usando XML Diff and Patch, sin embargo, parece que el diffgram producido se refiere a las ubicaciones exactas de nodo, tal como <xd:node match="1">, etc.

La solución ad-hoc es la más fácil, pero creo que es un poco engañosa. No sé XSLT muy bien, pero parece la mejor solución ...

¿Cuál es, en tu opinión, la "mejor herramienta para el trabajo"?

+0

Buena pregunta, +1. Consulte mi respuesta para ver los enlaces a dos utilidades de línea de comandos XSLT que usan procesadores Microsoft XSLT. En caso de que necesite el código XSLT exacto, publique un documento XML de muestra y también el resultado exacto que desea de la transformación. –

Respuesta

4

Usted puede utilizar las siguientes utilidades de línea de comandos XSLT para los procesadores XSLT Microsoft:

  1. msxsl.exe (ha estado allí por casi 10 años s). Realiza una transformación utilizando MSXML (es posible especificar diferentes versiones).

  2. Oleg Tkachenko's nxslt.exe utilidad de línea de comandos para XslCompiledTransform - esto es parte del proyecto Mvp.Xml.

3

En mi experiencia con XSLT podría funcionar, pero tenga en cuenta que le gustaría mantenerlo también. Hay una buena herramienta para construir xslt visual llamada MapForce que he usado en el pasado que podría ayudar.

Recientemente en el trabajo tuve que hacer una tarea similar: convertir el archivo XML de formato A a formato B, usar Linq fue el método más rápido y sencillo, y actualmente también es fácil de mantener.

Así que mi sugerencia es hacer lo más simple que funcione e ir a una solución rápida a menos que tenga beneficios claros de usar XSLT en su lugar.

+0

Cualquier idioma que conozcas bien sería más rápido que un idioma que no conoces. En general, usar LINQ como selector y luego hacer modificaciones con los métodos LINQ/DOM será menos poderoso (semánticamente) que XSLT (de la misma manera que cuando se compara XQuery con XSLT), lo que significa que tendrá un código LINQ más complejo que XSLT hoja de estilo –

+0

@Alejandro - tienes razón - pero si las transformaciones son lo suficientemente simples, no veo el sentido de usar XSLT donde dos líneas de Linq serían suficientes –

4

Si usar Xslt sería una opción, podría usar MSBuild para conducir la transformación en la línea de comando.

archivo de configuración App.config

<?xml version="1.0" encoding="utf-8"?> 
<configuration> 
    <runtime> 
     <assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1"> 
      <dependentAssembly> 
       <assemblyIdentity name="myAssembly" publicKeyToken="32ab4ba45e0a69a1" culture="neutral" /> 
       <bindingRedirect oldVersion="1.0.0.0" newVersion="2.0.0.0"/> 
      </dependentAssembly> 
     </assemblyBinding> 
    </runtime> 
</configuration> 

Xslt appconfig.xslt

Este XSLT muestra sería copiar todo, desde su app.config fuente y añadir un nodo <appSetting /> si no lo hace existir:

<?xml version="1.0" encoding="utf-8"?> 
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> 
    <xsl:output method="xml" indent="yes"/> 

    <xsl:template match="/"> 
     <xsl:apply-templates /> 
    </xsl:template> 

    <xsl:template match="configuration"> 
     <xsl:element name="configuration"> 
      <xsl:if test="self::node()[not(appSettings)]"> 
       <xsl:element name="appSettings" /> 
      </xsl:if> 
      <xsl:apply-templates /> 
     </xsl:element> 
    </xsl:template> 

    <xsl:template match="@* | node()"> 
     <xsl:copy> 
      <xsl:apply-templates select="@* | node()"/> 
     </xsl:copy> 
    </xsl:template> 
</xsl:stylesheet> 

script de MSBuild appconfig.proj

Este script proyecto MSBuild muestra copiará/copia de seguridad de su fuente app.config y transformarla con la hoja de estilo XSLT dado.

<Project ToolsVersion="4.0" DefaultTargets="Transform" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> 
    <ItemGroup> 
     <AppConfigFile Include="app.config" /> 
    </ItemGroup> 

    <Target Name="Clone"> 
     <Copy SourceFiles="@(AppConfigFile)" DestinationFiles="clone.config"> 
      <Output TaskParameter="CopiedFiles" ItemName="ClonedConfig" /> 
     </Copy> 
    </Target> 

    <Target Name="Transform" DependsOnTargets="Clone"> 
     <XslTransformation XslInputPath="appconfig.xslt" XmlInputPaths="@(ClonedConfig)" OutputPaths="app.config" /> 
    </Target> 
</Project> 

Correr desde la línea de comandos

<path to .NET framework 4>\MSBuild.exe appconfig.proj

+0

¡Guau, esto es extremadamente genial! ¡Ni siquiera pensé en aplicar MSBuild para esto! –

+0

@hmemcpy Supuse que su problema consistía en crear su aplicación para que MSBuild encajara perfectamente. Encontrará muchos ejemplos para modificar los archivos de configuración durante la compilación. – Filburt

Cuestiones relacionadas