Converting xliff to resx/resw as a build task
<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> | |
<Target Name="UpdateRuntimeResources"> | |
<ItemGroup> | |
<XLiffResources Include="$(MSBuildThisFileDirectory)\xliff_resources\**\*.xliff" /> | |
</ItemGroup> | |
<ImportResourceFiles XliffFiles="@(XLiffResources)" OutputDirectory="$(MSBuildThisFileDirectory)\LocalizedStrings" IsUWP="False" /> | |
</Target> | |
<UsingTask TaskName="ImportResourceFiles" TaskFactory="CodeTaskFactory" AssemblyFile="$(MSBuildToolsPath)\Microsoft.Build.Tasks.v4.0.dll"> | |
<ParameterGroup> | |
<XliffFiles ParameterType="Microsoft.Build.Framework.ITaskItem[]" Required="true" /> | |
<OutputDirectory ParameterType="System.String" Required="true" /> | |
<IsUWP ParameterType="System.Boolean" Required="true" /> | |
</ParameterGroup> | |
<Task> | |
<Reference Include="System.Core" /> | |
<Reference Include="System.Xml" /> | |
<Reference Include="WindowsBase" /> | |
<Using Namespace="System" /> | |
<Using Namespace="System.IO" /> | |
<Using Namespace="System.IO.Packaging" /> | |
<Using Namespace="System.Linq" /> | |
<Using Namespace="System.Net" /> | |
<Using Namespace="System.Xml" /> | |
<Using Namespace="Microsoft.Build.Framework" /> | |
<Using Namespace="Microsoft.Build.Utilities" /> | |
<Code Type="Fragment" Language="cs"> | |
<![CDATA[ | |
string zipTempPath = null; | |
string outfileDir = OutputDirectory; | |
Log.LogMessage("Output directory: " + OutputDirectory, MessageImportance.High); | |
try { | |
var inFiles = XliffFiles.Select(f => f.GetMetadata("FullPath")); | |
string outputFilename = "Resources"; | |
var files = new Dictionary<string, List<string>>(); | |
foreach (var infile in inFiles) | |
{ | |
var file = new System.IO.FileInfo(infile); | |
string languageId = file.Directory.Parent.Name; | |
if (!files.ContainsKey(languageId)) | |
files[languageId] = new List<string>(); | |
files[languageId].Add(infile); | |
} | |
foreach(var filelist in files) | |
{ | |
string languageId = filelist.Key; | |
string outfile = outfileDir; | |
if (languageId == "en") | |
languageId = "en-US"; | |
else if (languageId == "nb") | |
languageId = "nb-NO"; | |
if (IsUWP) | |
{ | |
outfile = System.IO.Path.Combine(outfile, languageId, outputFilename); | |
} | |
else | |
{ | |
if (languageId == "en-US") | |
outfile = System.IO.Path.Combine(outfile, outputFilename); | |
else | |
outfile = System.IO.Path.Combine(outfile, outputFilename + "." + languageId); | |
} | |
outfile += IsUWP ? ".resw" : ".resx"; | |
string message = "Generating resource for language '" + languageId + "'..."; | |
Console.WriteLine(message); | |
var d = new FileInfo(outfile).Directory; | |
if (!d.Exists) | |
d.Create(); | |
XmlWriterSettings settings = new XmlWriterSettings(); | |
settings.Indent = true; | |
using (XmlWriter writer = XmlWriter.Create(outfile, settings)) | |
{ | |
Dictionary<string, object> idChecker = new Dictionary<string, object>(); | |
writer.WriteStartDocument(); | |
writer.WriteStartElement("root"); | |
writer.WriteStartElement("resheader"); | |
writer.WriteAttributeString("name", "resmimetype"); | |
writer.WriteElementString("value", "text/microsoft-resx"); | |
writer.WriteEndElement(); //resheader | |
writer.WriteStartElement("resheader"); | |
writer.WriteAttributeString("name", "version"); | |
writer.WriteElementString("value", "2.0"); | |
writer.WriteEndElement(); //resheader | |
writer.WriteStartElement("resheader"); | |
writer.WriteAttributeString("name", "reader"); | |
writer.WriteElementString("value", "System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089"); | |
writer.WriteEndElement(); //resheader | |
writer.WriteStartElement("resheader"); | |
writer.WriteAttributeString("name", "writer"); | |
writer.WriteElementString("value", "System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089"); | |
writer.WriteEndElement(); //resheader | |
writer.WriteStartElement("data"); | |
writer.WriteAttributeString("name", "Resources_Language"); | |
writer.WriteAttributeString("xml", "space", "", "preserve"); | |
writer.WriteElementString("value", languageId); | |
writer.WriteEndElement(); //data | |
foreach (var infile in filelist.Value) | |
{ | |
var file = new System.IO.FileInfo(infile); | |
string filename = file.Name.Substring(0, file.Name.LastIndexOf('.')); | |
Console.WriteLine("\tProcessing ' " + infile + "'..."); | |
var fileExt = file.Extension.ToLowerInvariant(); | |
if (fileExt == ".xliff") | |
{ | |
using (XmlReader reader = XmlReader.Create(infile)) | |
{ | |
while (reader.ReadToFollowing("trans-unit")) | |
{ | |
string id = reader.GetAttribute("id"); | |
if (idChecker.ContainsKey(id)) | |
throw new InvalidOperationException("Duplicate resource ids detected"); | |
idChecker[id] = null; | |
string resourceString = null; | |
while (reader.Read() && reader.Name != "trans-unit") | |
{ | |
if (reader.Name == "target") | |
{ | |
resourceString = reader.ReadElementContentAsString(); | |
break; //target takes precedence over source | |
} | |
if (reader.Name == "source") | |
{ | |
resourceString = reader.ReadElementContentAsString(); | |
} | |
} | |
if (resourceString != null) | |
{ | |
writer.WriteStartElement("data"); | |
writer.WriteAttributeString("name", id); | |
writer.WriteAttributeString("xml", "space", "", "preserve"); | |
int index = -1; | |
for (int i = 1; i < 10; i++) | |
{ | |
while ((index = resourceString.IndexOf("%" + i.ToString() + "$s")) > -1) | |
{ | |
resourceString = resourceString.Replace("%" + i.ToString() + "$s", "{" + (i-1).ToString() + "}"); | |
} | |
} | |
if (resourceString.Contains("%")) | |
{ | |
throw new InvalidOperationException("String parameter placeholder not supported"); | |
} | |
writer.WriteElementString("value", resourceString); | |
writer.WriteEndElement(); //data | |
} | |
} | |
} | |
} | |
else if (fileExt == ".json") | |
{ | |
// Example: "output\resources\navigation\abbreviations\<LANG>.json" becomes "abbreviations__json" key | |
var id = file.Directory.Name + "_json"; | |
if (idChecker.ContainsKey(id)) | |
throw new InvalidOperationException("Duplicate resource ID detected: " + id); | |
idChecker[id] = null; | |
var jsonText = File.ReadAllText(infile); | |
writer.WriteStartElement("data"); | |
writer.WriteAttributeString("name", id); | |
writer.WriteElementString("value", jsonText); | |
writer.WriteEndElement(); //data | |
} | |
else | |
{ | |
throw new ArgumentException("Found a resource file of unknown file: " + infile); | |
} | |
} | |
writer.WriteEndElement(); //root | |
writer.WriteEndDocument(); | |
writer.Flush(); | |
writer.Close(); | |
} | |
} | |
return true; | |
} | |
catch (Exception ex) | |
{ | |
Log.LogErrorFromException(ex); | |
return false; | |
} | |
]]> | |
</Code> | |
</Task> | |
</UsingTask> | |
</Project> |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment