This project has moved and is read-only. For the latest updates, please go here.

How to remove orphaned entries?

Nov 11, 2013 at 12:29 PM

The seems like an excellent tool, but I have a question.
From description I read that this tool "...make it easy to [...] clean up orphaned entries", but where do I find this functionality? I can get the ResXManager to load in VS and bring up all the resx entries, but where should I go from there? I am using VS2012.

Currently I have resx files with 300-400 entries in 5 languages, but as time passes developers sometime forget to delete obsolete resx entries. This means we spent a lot of time translating entries that are obsolete.

Hoping for some help.
Nov 12, 2013 at 2:38 PM
"cleanup orphaned entries" only meant to easily find translations with no correspondent neutral entry.
This frequently happens with WinForms controls - when you remove a child control, the neutral entry is removed but often it's translation stays as orphan entry.

Maybe I can add the feature you need in a later version, but it's not a trivial issue, so don't expect something in near future.
Nov 12, 2013 at 2:48 PM
Edited Nov 12, 2013 at 3:02 PM
Thanks for quick answer,. I have modified the powershell code below to clean up unused resx elements. It is inspired from another script. I am not sure how easy this would be to adapt to ResXManager, but the script works perfectly.
# Script: Removed unused resx strings in a single file:
# How to use: Run this command from powershell: Fix-Resx D:\Res.resx D:\trunk -filepattern *.cs, *.cshtml, *.aspx
# - this command will look through .cs, .cshtml, and .aspx files for unused resx values in a file called Res.resx.
# original:

function Fix-Resx
         [Parameter(Position=0, Mandatory=$true)]

         [Parameter(Position=1, Mandatory=$true)]

     if ((Test-Path $resourceFile) -eq $false)
         Write-Output ""
         Write-Output "File" $resourceFile "doesn't exist."
         Write-Output ""
     # Read the resource file
     [xml]$xml = get-content $resourceFile
    # Check for any resources
     if ($ -eq $null)
         Write-Output ""
         Write-Output "File" $resourceFile "contains no resource identifiers."
         Write-Output ""
    # Extract the resource identifiers
     $identifiers = @()
     foreach ($elem in $ { $identifiers += $elem.GetAttribute("name") }
    # Get all the files in the root path that match the pattern. Exclude the resource designer file
    $resourceDesignerFiles = (Get-Item $resourceFile).PSChildName.Replace(".resx", ".*Designer.cs")
     $files = gci $rootPath -recurse -include $filePattern -Exclude $resourceDesignerFiles
    # Iterate the identifiers and look for references in the files
     $found = @()
     foreach ($identifier in $identifiers)
         foreach ($file in $files)
             $check = select-string -pattern $identifier $file
             if ($check -ne $null)
                 $found += $identifier
    # Subtract the found identifiers from the original list
    $diffs = Compare-Object $identifiers $found
     Write-Output ""
     Write-Output "Unused string resources in "
     Write-Output $resourceFile
     Write-Output "----------------------------------------------------------------------------"
     if ($diffs -eq $null)
         Write-Output "No unused strings found."
         Write-Output ""
    # Store only the identifiers out of the differences object
     $diffslist = @()
     foreach ($diffObj in $diffs) { $diffslist += $diffObj.InputObject }

    # Sort the list and output it
     $diffslist = $diffslist | Sort-Object
     $i = 0

     foreach ($diffObj in $diffslist) { 
        # remove unused resx elements  
        $keyNode = $ | Where-Object { $_.GetAttribute("name") -eq $diffObj }
        $xml.root.RemoveChild($keyNode) > $null
        Write-Output $diffObj

    $i = $i.ToString() + " element(s) removed!"

    Write-Output $i
    Write-Output ""