zoukankan      html  css  js  c++  java
  • C#资源文件比对与自动翻译。

    先暂时记录下,界面以后有时间做,做这个主要是因为有一份资源文件,对应英,简,繁。现在的情况就是英文最全,然后简体次之,繁体最不全,因为直接从英文翻译到繁体错误几率大,所以要求先从简翻译到繁。其实这种网上工具也有,用了一下感觉太复杂,不好操作,要么全部给翻译了(这也就没有意义了),于是自己写一个,先做完再说。

     

    资源文件需要处理的数据主要有几种形式.

        <data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
        <data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
        <data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
            <value>[base64 mime encoded serialized .NET Framework object]</value>
        </data>
        <data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
            <value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
            <comment>This is a comment</comment>
        </data>
      <data name="title" xml:space="preserve">
        <value>Title</value>
      </data>
      <data name="titleComment" xml:space="preserve">
        <value>Title</value>
        <comment>comment</comment>
      </data>
    

    定义如下一个类,主要描述这几种形式的公共处理方式。

       public class ResxData : ICloneable
        {
            public const string str_data = "data";
            public const string str_name = "name";
            public const string str_value = "value";
            public const string str_comment = "comment";
            public string Name { get; set; }
            public string Value { get; set; }
            public string Comment { get; set; }
    
            public virtual XmlElement InsertElement(XmlDocument doc)
            {
                XmlElement dataElement = doc.CreateElement(str_data);
                dataElement.SetAttribute(str_name, Name);
                if (!string.IsNullOrEmpty(Value))
                {
                    XmlElement valueElement = doc.CreateElement(str_value);
                    valueElement.InnerText = Value;
                    dataElement.AppendChild(valueElement);
                }
                if (!string.IsNullOrEmpty(Comment))
                {
                    XmlElement commentElement = doc.CreateElement(str_comment);
                    commentElement.InnerText = Comment;
                    dataElement.AppendChild(commentElement);
                }
                return dataElement;
            }
            public XmlElement InsertElement(XmlDocument doc, bool bAdd)
            {
                var element = InsertElement(doc);
                if (bAdd)
                    doc.DocumentElement.AppendChild(element);
                return element;
            }
    
            public virtual object Clone()
            {
                ResxData data = new ResxData();
                data.Name = this.Name;
                data.Value = this.Value;
                data.Comment = this.Comment;
                return data;
            }
        }

    因为我要做的只是针对后面加个属性的那种资源文件,没有那种对应type的那种,所以我暂时只做一个扩展。

        public class ResxDataSpace : ResxData
        {
            public const string str_space = "space";
            public const string str_nameSpace = "xml:space";
            public string Space { get; set; }
            public override XmlElement InsertElement(XmlDocument doc)
            {
                var element = base.InsertElement(doc);
                element.SetAttribute(str_nameSpace, Space);
                return element;
            }
            public override object Clone()
            {
                ResxData data = base.Clone() as ResxData;
                if (data != null)
                {
                    ResxDataSpace space = GetData(data, Space);
                    return space;
                }
                return data;
            }
    
            public static ResxDataSpace GetData(ResxData data, string spaceValue)
            {
                ResxDataSpace space = new ResxDataSpace();
                space.Name = data.Name;
                space.Value = data.Value;
                space.Comment = data.Comment;
                space.Space = spaceValue;
                return space;
            }
        }

    然后是对应文件的处理类。

        public class ReadResxData
        {
            public const string str_root = "root";
            public const string str_sperate = "/";
            private string filePath;
            public string FilePath
            {
                get
                {
                    return filePath;
                }
                set
                {
                    filePath = value;
                    string fileName = Path.GetFileName(filePath);
                    string[] sp = fileName.Split('.');
                    if (sp.Length > 1)
                    {
                        if (sp.Length > 2)
                        {
                            Mark = sp[1];
                        }
                        else
                        {
                            Mark = "en-US";
                        }
                    }
                }
            }
            public string Mark { get; set; }
    
            public List<ResxData> GetData()
            {
                System.Xml.XmlDocument xmlDoc = new System.Xml.XmlDocument();
                xmlDoc.Load(FilePath);
                XmlNodeList nodes = xmlDoc.SelectNodes(str_root + str_sperate + ResxData.str_data);
                List<ResxData> datas = new List<ResxData>();
                foreach (XmlNode node in nodes)
                {
                    ResxData resxData = new ResxData();
                    resxData.Name = node.Attributes[ResxData.str_name].InnerText;
                    if (node.ChildNodes.Count > 0)
                    {
                        XmlNode valueNode = node.SelectSingleNode(ResxData.str_value);
                        XmlNode commentNode = node.SelectSingleNode(ResxData.str_comment);
                        if (valueNode != null)
                        {
                            resxData.Value = valueNode.InnerText;
                        }
                        if (commentNode != null)
                        {
                            resxData.Comment = valueNode.InnerText;
                        }
                    }
                    var spaceAttributes = node.Attributes[ResxDataSpace.str_nameSpace];
                    if (spaceAttributes != null)
                    {
                        ResxDataSpace space = ResxDataSpace.GetData(resxData, spaceAttributes.Value);
                        datas.Add(space);
                    }
                    else
                    {
                        datas.Add(resxData);
                    }
                }
                return datas;
            }
    
            public XmlDocument GetDoc()
            {
                XmlDocument doc = new XmlDocument();
                doc.Load(FilePath);
                return doc;
            }
        }

    然后就需要比对文件。

        public class CompareResxData
        {
            public ReadResxData Source { get; set; }
    
            public ReadResxData Des { get; set; }
    
            public CompareResxData()
            {
                Source = new ReadResxData();
                Des = new ReadResxData();
            }
            private string sourceFilePath;
            public string SourceFilePath
            {
                get
                {
                    return sourceFilePath;
                }
                set
                {
                    sourceFilePath = value;
                    Source.FilePath = sourceFilePath;
                }
            }
            private string desFilePath;
            public string DesFilePaht
            {
                get
                {
                    return desFilePath;
                }
                set
                {
                    desFilePath = value;
                    Des.FilePath = desFilePath;
                }
            }
    
            public List<ResxData> CompareFormT()
            {
                var souDatas = Source.GetData();
                var desDatas = Des.GetData();
    
                List<ResxData> results = new List<ResxData>();
                foreach (var souData in souDatas)
                {
                    var result = desDatas.FirstOrDefault(p => p.Name == souData.Name);
                    if (result == null || string.IsNullOrEmpty(result.Value))
                    {
                        results.Add(souData);
                    }
                }
                return results;
            }
    
        }

    翻译比较简单,主要是参考http://www.cnblogs.com/gsyifan/archive/2011/11/14/microsoft_Translate_api.html引用service实现。

        public class TranslateLanguage
        {
            public const string appID = "82A171654F003025C2524F9AFDA1951A6D116C89";
            private static LanguageService.LanguageServiceClient client = new LanguageService.LanguageServiceClient();
            public static string Translate(string value, string from, string to)
            {
                string result = client.Translate(appID, value, from, to, "text/html", "general");
                return result;
            }
    
        }

    最后是测试功能如下,实现的结果还是比较可以。

        public class Test
        {
            public void t1()
            {
                CompareResxData c = new CompareResxData();
                c.SourceFilePath = @"D:\WorkSpace\resx\Strings.zh-CHS.resx";
                c.DesFilePaht = @"D:\WorkSpace\resx\Strings.zh-CHT.resx";
                var tt = c.CompareFormT();
                List<ResxData> ts = new List<ResxData>();
                object obj = new object();
                Parallel.For(0, tt.Count, (i) =>
                {
                    var s = tt[i];
                    string result = TranslateLanguage.Translate(s.Value, c.Source.Mark, c.Des.Mark);
                    ResxData data = s.Clone() as ResxData;
                    s.Value = result;
                    lock (obj)
                    {
                        ts.Add(s);
                    }
                });
                var doc = c.Des.GetDoc();
                foreach (var s in ts)
                {
                    s.InsertElement(doc, true);
                }
                doc.Save(c.Des.FilePath);
            }
        }

    主要实现就是如上,当然后面要加上一些界面,还有一些辅助处理的类,以便处理更多的情况。

  • 相关阅读:
    树状数组
    线段树
    最短路(FLOYD)
    欧拉函数
    筛素数
    并查集
    背包方案数问题(礼物)
    [BeijingWc2008]雷涛的小猫
    受欢迎的牛[HAOI2006]
    删除物品[JLOI2013]
  • 原文地址:https://www.cnblogs.com/zhouxin/p/2442915.html
Copyright © 2011-2022 走看看