Herramienta de reemplazo de XML de CSV

Tengo archivos XML donde quiero reemplazar ciertas cadenas.

La fuente de reemplazo es un archivo CSV que contiene 2 columnas

old       |           new
-------------------------
OldPart1  |  NewPartName1
OldPart2  |  NewPartName2
OldPart3  |  NewPartName3

Quiero reemplazar todas las apariciones de oldcon newen los archivos XML. Supongo que realmente no importa si los archivos son XML o solo texto. Las cadenas de reemplazo no chocan con los nombres de las etiquetas XML.

¿Has probado editores de texto simples como Notepad y Notepad++?
Sí, no encontró un método para reemplazos masivos.
En Notepad++, presione Ctrl+H para abrir el cuadro de diálogo Buscar y reemplazar.
Lo sé. ¿Y dónde elijo el archivo CSV para reemplazar 1000 cadenas diferentes una tras otra?
Te entendí mal, lo siento. No creo que haya editores que respalden su requisito especial. Experimenté un poco con PowerShell (es divertido). Por favor, vea mi respuesta.

Respuestas (2)

Un poco de magia de PowerShell.

Comentarios adicionales:

  • Su archivo CSV no debe contener encabezados y debe usarse ;como delimitadores.
  • Su entrada y el archivo CSV deben estar codificados en UTF-8 o UTF-16. PowerShell no puede adivinar automáticamente otras codificaciones.
  • El script no se cerrará si especifica nombres de archivo no válidos. No espere que se abra un buen cuadro de diálogo de error :)
<#
  Copied from: http://blogs.technet.com/b/heyscriptingguy/archive/2009/09/01/hey-scripting-guy-september-1.aspx
  Many thanks to the Scripting Guy :)
  Changes:
    - Added a title parameter and assigned it to $OpenFileDialog.title
    - Changed the function's name to Get-OpenFile
#>
Function Get-OpenFile($initialDirectory, $title)
{   
 [System.Reflection.Assembly]::LoadWithPartialName("System.windows.forms") |
 Out-Null

 $OpenFileDialog = New-Object System.Windows.Forms.OpenFileDialog
 $OpenFileDialog.title = $title;
 $OpenFileDialog.initialDirectory = $initialDirectory
 $OpenFileDialog.filter = "All files (*.*)| *.*"
 $OpenFileDialog.ShowDialog() | Out-Null
 $OpenFileDialog.filename
} #end function Get-FileName

Function Get-SaveFile($initialDirectory, $title)
{   
 [System.Reflection.Assembly]::LoadWithPartialName("System.windows.forms") |
 Out-Null

 $OpenFileDialog = New-Object System.Windows.Forms.SaveFileDialog
 $OpenFileDialog.title = $title;
 $OpenFileDialog.initialDirectory = $initialDirectory
 $OpenFileDialog.filter = "All files (*.*)| *.*"
 $OpenFileDialog.ShowDialog() | Out-Null
 $OpenFileDialog.filename
} #end function Get-OpenFile

# $PSScriptRoot is only available for PowerShell >= 3
# Fallback needed
$scriptDir = $PSScriptRoot

$inputFile = Get-OpenFile -initialDirectory $scriptDir -title "Choose your input file"
$csvFile = Get-OpenFile -initialDirectory $scriptDir -title "Choose your CSV file"

$inputStr = [Io.File]::ReadAllText($inputFile);
$csvData = Import-Csv $csvFile -Header @("Needle", "Replacement") -Delimiter ';'

$csvData | % {
    $inputStr = $inputStr.Replace($_.needle, $_.replacement);
}

$outputFilename = Get-SaveFile -initialDirectory $scriptDir -title "Save your file"
$inputStr | Out-File -FilePath $outputFilename

Usando python , (disponible en/para la mayoría de las plataformas y gratis), y asumiendo que su archivo xml cabe en la memoria y que el separador es, sin espacio:

with open(r"XML/File/Name").read() as xml: 
    with open(r"Path/To/Output/File", "w") as outfile:
        for line in open(r"CSV/File/Name").readlines():
            (orig, replacement) = ','.split(line) # Change ',' to your separator
            xml.replace(orig, replacement)
            outfile.writeline(line)

Estoy seguro de que hay formas mejores/más genéricas de hacer esto, pero es tarde en este momento.