Modifying .resx file in C#
Solution 1:
There's a whole namespace for resource management: System.Resources. Check out the ResourceManager class, as well as ResXResourceReader and ResXResourceWriter.
http://msdn.microsoft.com/en-us/library/system.resources.aspx
I managed to lay my hands on a very old debug method that I used to use at one point when I was testing some resource related stuff. This should do the trick for you.
public static void UpdateResourceFile(Hashtable data, String path)
{
Hashtable resourceEntries = new Hashtable();
//Get existing resources
ResXResourceReader reader = new ResXResourceReader(path);
if (reader != null)
{
IDictionaryEnumerator id = reader.GetEnumerator();
foreach (DictionaryEntry d in reader)
{
if (d.Value == null)
resourceEntries.Add(d.Key.ToString(), "");
else
resourceEntries.Add(d.Key.ToString(), d.Value.ToString());
}
reader.Close();
}
//Modify resources here...
foreach (String key in data.Keys)
{
if (!resourceEntries.ContainsKey(key))
{
String value = data[key].ToString();
if (value == null) value = "";
resourceEntries.Add(key, value);
}
}
//Write the combined resource file
ResXResourceWriter resourceWriter = new ResXResourceWriter(path);
foreach (String key in resourceEntries.Keys)
{
resourceWriter.AddResource(key, resourceEntries[key]);
}
resourceWriter.Generate();
resourceWriter.Close();
}
Solution 2:
public static void AddOrUpdateResource(string key, string value)
{
var resx = new List<DictionaryEntry>();
using (var reader = new ResXResourceReader(resourceFilepath))
{
resx = reader.Cast<DictionaryEntry>().ToList();
var existingResource = resx.Where(r => r.Key.ToString() == key).FirstOrDefault();
if (existingResource.Key == null && existingResource.Value == null) // NEW!
{
resx.Add(new DictionaryEntry() { Key = key, Value = value });
}
else // MODIFIED RESOURCE!
{
var modifiedResx = new DictionaryEntry()
{ Key = existingResource.Key, Value = value };
resx.Remove(existingResource); // REMOVING RESOURCE!
resx.Add(modifiedResx); // AND THEN ADDING RESOURCE!
}
}
using (var writer = new ResXResourceWriter(ResxPathEn))
{
resx.ForEach(r =>
{
// Again Adding all resource to generate with final items
writer.AddResource(r.Key.ToString(), r.Value.ToString());
});
writer.Generate();
}
}
Solution 3:
If you want to keep the existing comments in the resource files then use this (Based on SirMoreno's code modified)
public static void UpdateResourceFile(Hashtable data, String path)
{
Hashtable resourceEntries = new Hashtable();
//Get existing resources
ResXResourceReader reader = new ResXResourceReader(path);
reader.UseResXDataNodes = true;
ResXResourceWriter resourceWriter = new ResXResourceWriter(path);
System.ComponentModel.Design.ITypeResolutionService typeres = null;
if (reader != null)
{
IDictionaryEnumerator id = reader.GetEnumerator();
foreach (DictionaryEntry d in reader)
{
//Read from file:
string val = "";
if (d.Value == null)
resourceEntries.Add(d.Key.ToString(), "");
else
{
val = ((ResXDataNode)d.Value).GetValue(typeres).ToString();
resourceEntries.Add(d.Key.ToString(), val);
}
//Write (with read to keep xml file order)
ResXDataNode dataNode = (ResXDataNode)d.Value;
//resourceWriter.AddResource(d.Key.ToString(), val);
resourceWriter.AddResource(dataNode);
}
reader.Close();
}
//Add new data (at the end of the file):
Hashtable newRes = new Hashtable();
foreach (String key in data.Keys)
{
if (!resourceEntries.ContainsKey(key))
{
String value = data[key].ToString();
if (value == null) value = "";
resourceWriter.AddResource(key, value);
}
}
//Write to file
resourceWriter.Generate();
resourceWriter.Close();
}
Solution 4:
Womp got it right (10x).
But here is a code that keeps the XML file order, add new at the end of the file. (for source control)
//Need dll System.Windows.Forms
public static void UpdateResourceFile(Hashtable data, String path)
{
Hashtable resourceEntries = new Hashtable();
//Get existing resources
ResXResourceReader reader = new ResXResourceReader(path);
ResXResourceWriter resourceWriter = new ResXResourceWriter(path);
if (reader != null)
{
IDictionaryEnumerator id = reader.GetEnumerator();
foreach (DictionaryEntry d in reader)
{
//Read from file:
string val = "";
if (d.Value == null)
resourceEntries.Add(d.Key.ToString(), "");
else
{
resourceEntries.Add(d.Key.ToString(), d.Value.ToString());
val = d.Value.ToString();
}
//Write (with read to keep xml file order)
resourceWriter.AddResource(d.Key.ToString(), val);
}
reader.Close();
}
//Add new data (at the end of the file):
Hashtable newRes = new Hashtable();
foreach (String key in data.Keys)
{
if (!resourceEntries.ContainsKey(key))
{
String value = data[key].ToString();
if (value == null) value = "";
resourceWriter.AddResource(key, value);
}
}
//Write to file
resourceWriter.Generate();
resourceWriter.Close();
}