I work on websites where we have several resource files that are localized in many languages. This makes operations like renaming a resource key and moving a resource key to a different file annoying since you must do it across several languages. To help with this I created a couple of PowerShell scripts to automate this process.
These PowerShell scripts assume your .resx files live in a folder named “Resources” but this can be easily changed.
RenameResource.ps1
param([String]$keyOld, [String]$keyNew)
if(-not $keyOld -or -not $keyOld) {
echo "RenameResource.ps1 keyOld keyNew"
return
}
$files=get-childitem Resources *.resx
foreach($file in $files) {
$xml = [xml](Get-Content $file.FullName)
$dataNode = $xml.root.data | Where-Object { $_.GetAttribute("name") -eq $keyOld }
if ($dataNode -ne $null) {
$dataNode.SetAttribute("name", $keyNew)
$xml.Save($file.FullName)
}
}
MoveResource.ps1
param([String]$resourceNameSource, [String]$resourceNameDestination, [string] $keyName)
if(-not $resourceNameSource -or -not $resourceNameDestination -or -not $keyName) {
echo "MoveResource.ps1 resourceNameSource resourceNameDestination keyName"
return
}
$sourceFiles = Get-ChildItem "Resources\$resourceNameSource*.resx"
$destFiles = Get-ChildItem "Resources\$resourceNameDestination*.resx"
$mapping = @{}
$sourceFiles | foreach {
$parts = $_ -split "\."
$list = New-Object "system.collections.arraylist"
$list.Add($_) > $null
if($parts.Length -eq 2) {
$mapping["en-us"] = $list
}
else {
$mapping[$parts[1]] = $list
}
}
$destFiles | foreach {
$parts = $_ -split "\."
if($parts.Length -eq 2) {
$mapping["en-us"].Add($_ ) > $null
}
else {
$mapping[$parts[1]].Add($_ ) > $null
}
}
foreach($pair in $mapping.Values) {
$sourcePath = $pair[0]
$destPath = $pair[1]
$source = [xml](Get-Content $sourcePath)
$dest = [xml](Get-Content $destPath)
$keyNodeSource = $source.root.data | Where-Object { $_.GetAttribute("name") -eq $keyName }
$keyNodeDest = $dest.root.data | Where-Object { $_.GetAttribute("name") -eq $keyName }
if ($keyNodeSource -eq $null) {
echo "Key does not exist in source"
return;
}
if($keyNodeDest -ne $null) {
echo "Key already exists in destination"
return;
}
try
{
$newNode = $dest.ImportNode($keyNodeSource.Clone(), $true)
$source.root.RemoveChild($keyNodeSource) > $null
$dest.root.AppendChild($newNode) > $null
$dest.Save($destPath)
$source.Save($sourcePath)
}
catch {
Write-Host "Error text: " $_
return
}
}
Usage
Renaming a resource key:
.\RenameResource.ps1 oldKey newKey
Moving a resource with key “keyName” from a file named “ResourceFile1.resx” to “ResourceFile2.resx”:
.\MoveResource.ps1 ResourceFile1 ResourceFile2 keyName

One thought on “Moving and renaming resource keys in a .resx file”
Comments are closed.