private static void ResourceSet2Resx(ResourceSet resourceSet, Stream outputStream, string xsltFileName) { Stream temporaryStream; // If xslt was provided then use a temporary memory stream to save // content. Later the content will be saved to final output stream after // xsl transformation. If xslt was not provided then save to the given output stream. if (!string.IsNullOrEmpty(xsltFileName)) { temporaryStream = new MemoryStream(); } else { temporaryStream = outputStream; } ResourceSet2Resx(resourceSet, temporaryStream); // if xslt was provided then convert the output stream // using that xslt file if (!string.IsNullOrEmpty(xsltFileName)) { // move current position of temporary stream to beginning because previous method // left it at the end after completing writing to it temporaryStream.Position = 0; ApplyXslt(temporaryStream, xsltFileName, outputStream); } }
/// <summary> /// Loads a .resx file (given it's full file path) into a <see cref="ResourceSet"/> /// </summary> private static void Resx2ResourceSet(ResourceSet resourceSet, string file, string xsltFile) { Stream inputStream = File.OpenRead(file); // if xslt was provided then do not use the file directly. // convert it using xslt and use output instead if (!string.IsNullOrEmpty(xsltFile)) { var outputStream = new MemoryStream(); ApplyXslt(inputStream, xsltFile, outputStream); inputStream = outputStream; } using (inputStream) { Resx2ResourceSet(resourceSet, inputStream); } }
internal static void ResourceSet2Resx(ResourceSet resourceSet, Stream stream) { var writer = new ResXResourceWriter(stream); var orderedResourceItems = resourceSet.Values.OrderBy(ri => ri.Name); foreach (ResourceItem resourceItem in orderedResourceItems) { var resourceNode = new ResXDataNode(resourceItem.Name, resourceItem.Value); // create comment from actual comment and other metadata (maxlenght, locked etc) var comment = resourceItem.Comment; var resourceStringItem = resourceItem as ResourceStringItem; if (resourceStringItem != null && resourceStringItem.MaxLength != ResourceStringItem.UnlimitedLength) { comment = resourceStringItem.MaxLength + "#" + comment; } else if (resourceItem.LockedReason == LockedReason.DeveloperLock) { comment = "#" + comment; } else if (resourceItem.ReviewPending) { comment = "?" + comment; } if (!string.IsNullOrEmpty(comment)) { resourceNode.Comment = comment; } // check for empty value. empty values should not exist // to resource files so that the corresponding values from the neutral // resource file is used instead // Update: This should not be checked for neutral culture if (resourceSet.Culture == "neutral" || !resourceItem.ValueEmpty) { writer.AddResource(resourceNode); } } writer.Generate(); // this command behaves like flush in a stream. it writes to the stream behind all pending changes. }
private static void ResourceSet2Resx(ResourceSet resourceSet, string file, string xsltFileName) { // copy target file (if already exists) to temporary location, just in case operation fails string temporaryFileName = null; if (File.Exists(file)) { temporaryFileName = Path.Combine(Path.GetTempPath(), Path.GetRandomFileName()); File.Copy(file, temporaryFileName); } // delete target file File.Delete(file); try { using (var outputStream = File.Open(file, FileMode.CreateNew, FileAccess.Write, FileShare.None)) { ResourceSet2Resx(resourceSet, outputStream, xsltFileName); } } catch (Exception ex) { if (string.IsNullOrEmpty(temporaryFileName)) { throw new InvalidOperationException(string.Format("Failed to write to '{0}'.", file), ex); } else { throw new InvalidOperationException(string.Format("Failed to write to '{0}'. Original content of the file can be found here '{1}'.", file, temporaryFileName), ex); } } // delete temporary file (if one was created) now that everything went fine if (!string.IsNullOrEmpty(temporaryFileName)) { File.Delete(temporaryFileName); } }
/// <summary> /// Loads a .resx file (given a stream with it's content) into the given <see cref="ResourceSet"/> /// </summary> internal static void Resx2ResourceSet(ResourceSet resourceSet, Stream stream) { ResourceItem resourceItem; ResourceStringItem resourceStringItem; string resourceComment; ResXDataNode res; object value; var reader = new ResXResourceReader(stream); reader.UseResXDataNodes = true; var assemblyNames = new System.Reflection.AssemblyName[] { }; // this is used as parameter of GetValue since there is no overload that accepts no parameter foreach (DictionaryEntry item in reader) { res = (ResXDataNode)item.Value; // resource item has file reference then special care must be taken if (res.FileRef == null) { value = res.GetValue(assemblyNames); } else { value = res.FileRef; } resourceComment = res.Comment; int sharpPosition = -1; if (!string.IsNullOrEmpty(resourceComment)) { sharpPosition = resourceComment.IndexOf("#", StringComparison.OrdinalIgnoreCase); } if (resourceComment == null) { resourceComment = string.Empty; } if (value != null) { switch (value.GetType().Name) { case "String": resourceStringItem = new ResourceStringItem(); resourceItem = resourceStringItem; if (sharpPosition > 0) { int tempValue; if (int.TryParse(resourceComment.Substring(0, sharpPosition), out tempValue)) { resourceStringItem.MaxLength = tempValue; resourceComment = resourceComment.Substring(sharpPosition + 1); } } break; default: resourceItem = new ResourceItem(); break; } } else { resourceItem = new ResourceItem(); } resourceItem.Name = res.Name; resourceItem.Value = value; LockedReason resourceLockedReason = LockedReason.Unknown; // lock local value if base comment begins with # bool resourceLocked; if (sharpPosition == 0) { resourceLocked = true; resourceLockedReason = LockedReason.DeveloperLock; resourceComment = resourceComment.Substring(1); } else { resourceLocked = false; } if (resourceItem.Name.StartsWith(">>", StringComparison.OrdinalIgnoreCase)) { resourceLocked = true; resourceLockedReason = LockedReason.FrameworkLock; } if (resourceComment.StartsWith("@", StringComparison.OrdinalIgnoreCase)) { resourceLocked = true; resourceLockedReason = LockedReason.ResexMetadata; } if (resourceComment.StartsWith("?", StringComparison.OrdinalIgnoreCase)) { resourceComment = resourceComment.Substring(1); resourceItem.ReviewPending = true; } resourceItem.Comment = resourceComment; resourceItem.Locked = resourceLocked; resourceItem.LockedReason = resourceLockedReason; // add item to collection resourceSet.Add(resourceItem.Name, resourceItem); } }
public virtual ResourceBundle Load(string fileName) { var baseFileInfo = new FileInfo(fileName); var basePath = baseFileInfo.DirectoryName ?? string.Empty; // if extension of input file is not .resx and an xslt file to convert an xml into valid resx exists, then use it // else consider that the input file is .resx already string xsltFile = string.Empty; if (!string.Equals(baseFileInfo.Extension, ".resx", StringComparison.InvariantCultureIgnoreCase)) { var xsltFullPath = Path.Combine(basePath, xsltConvertToResx); xsltFile = FileSystem.FileExists(xsltFullPath) ? xsltFullPath : null; } var extractCultureFromFile = new ResxExtractCultureFromFileStrategy(); // define the search patterh (eg. MyFile.*.resx) that will be used to detect files of // other cultures, given the input file string searchPattern = fileName; var cultureOfInputFile = extractCultureFromFile.GetCulture(baseFileInfo.Name); if (cultureOfInputFile != ResourceSet.NeutralCulture) { // if input file contains culture information, then remove it searchPattern = extractCultureFromFile.ReplaceCulture(searchPattern, string.Empty); baseFileInfo = new FileInfo(searchPattern); } // put a wildcard before the extension searchPattern = Path.GetFileNameWithoutExtension(searchPattern) + "*" + baseFileInfo.Extension; var resourceBundle = new ResourceBundle(); foreach (string file in this.FileSystem.GetFiles(basePath, searchPattern, SearchOption.TopDirectoryOnly)) { try { if (baseFileInfo.FullName == extractCultureFromFile.ReplaceCulture(file, string.Empty)) { var culture = extractCultureFromFile.GetCulture(file); // If neutral culture was detected for the second time, we are skipping the file // There are two reasons that this can happen: // a) The ResxExtractCultureFromFileStrategy failed to detect a know culture the file name and returned neutral // b) File name is not part of the same resource bundle but happens to have similar name that pas the same prefix and .resx extension // eg. our main file name could be MyFile.resx and this file name could be MyFile.Version2.resx if (culture == ResourceSet.NeutralCulture && resourceBundle.ContainsCulture(culture)) { continue; } var resourceSet = new ResourceSet(culture); Resx2ResourceSet(resourceSet, file, xsltFile); resourceBundle.Add(resourceSet); } } catch (Exception ex) { throw new InvalidOperationException(string.Format("Failed to open file '{0}'", file), ex); } } return(resourceBundle); }