用XML代替程序中信息显示的硬编码

程序中通常会有一些错误代码或标识,为了程序中方便这些东西通常不会使用汉字,经常在程序中用的是一些FileError或数字。还有就是在编码中经常使用的枚举标识对象的状态。
通常这些信息会直接的或间接的显示给用户,可用户需要到的是容易理解的汉字描述。以前要么将这些标识和枚举的转换规则硬编码到程序中,要么就直接提示给用户。
前者没有很好的扩展性,而后者则让用户一头雾水。现可以用流行的XML(配置文件)保存提示信息,然后用一个对象将机器中的内码转换为人们容易理解的信息。

转换对象如下:

     /// <summary>
    
/// 翻译类,将内部码翻译成容易理解的中文
    
/// </summary>
    
/// <remarks>
    
/// 根据配置文件中的信息,将系统内部码(错误码、成功码)翻译成中文(或人容易理解的语言)。
    
/// </remarks>

     public   static   class  Translation
    
{
        
private static System.IO.FileSystemWatcher watcher;
        
private static XmlDocument content;
        
private static string configFile;
        
private static object locker = new object();

        
/// <summary>
        
/// 加载配置文件
        
/// </summary>
        
/// <param name="configFile"></param>

        public static void Configure(string configFile)
        
{
            LoadFile(configFile);
            
if (watcher != null)
            
{
                watcher.Dispose();
            }

            watcher 
= new FileSystemWatcher(Path.GetDirectoryName(configFile), Path.GetFileName(configFile));
            watcher.Changed 
+= new FileSystemEventHandler(watcher_Changed);
        }


        
/// <summary>
        
/// 加载默认配置文件
        
/// </summary>

        public static void Configure()
        
{
            
if (System.Web.HttpContext.Current != null)
            
{
                Configure(System.Web.HttpContext.Current.Server.MapPath(
"~/translation.config"));
            }

            
else
            
{
                Configure(System.AppDomain.CurrentDomain.SetupInformation.ApplicationBase 
+ "/" + "translation.config");
            }

        }


        
/// <summary>
        
/// 加载文件内容
        
/// </summary>
        
/// <param name="configFile"></param>

        private static void LoadFile(string configFile)
        
{
            
lock (locker)
            
{
                XmlDocument doc 
= new XmlDocument();
                doc.Load(configFile);

                content 
= doc;
                Translation.configFile 
= configFile;
            }

        }


        
/// <summary>
        
/// 当文件变更时,从新加载文件
        
/// </summary>
        
/// <param name="sender"></param>
        
/// <param name="e"></param>

        private static void watcher_Changed(object sender, FileSystemEventArgs e)
        
{
            LoadFile(configFile);
        }


        
/// <summary>
        
/// 获取Enum的解释,如果Enum有Flag标记,则使用逗号分隔各个解释
        
/// </summary>
        
/// <param name="enumValue"></param>
        
/// <returns></returns>

        public static string GetEnumDescription(Enum enumValue)
        
{
            
return GetEnumDescription(enumValue, ",");
        }


        
/// <summary>
        
/// 获取Enum的解释,如果Enum有Flag标记,则使用sparator分隔各个解释
        
/// </summary>
        
/// <param name="enumValue"></param>
        
/// <param name="sparator"></param>
        
/// <returns></returns>

        public static string GetEnumDescription(Enum enumValue, string sparator)
        
{
            Type type 
= enumValue.GetType();

            
//检查类型是否有Flags特性
            object[] attrs = type.GetCustomAttributes(typeof(FlagsAttribute), false);
            
if (attrs.Length > 0)
            
{
                StringBuilder builder 
= new StringBuilder();
                Array arr 
= Enum.GetValues(type);
                
foreach (Enum enu in arr)       //循环获取每一个值的解释
                {
                    
if ((Convert.ToUInt64(enumValue) & Convert.ToUInt64(enu)) == Convert.ToUInt64(enu))     //判断是否有这个值
                    {
                        builder.Append(GetEnumDes(type, enu.ToString()));
                        builder.Append(sparator);
                    }

                }

                
if (builder.Length != 0)        //拿掉最后的分隔符
                    builder.Remove(builder.Length - sparator.Length, sparator.Length);
                
return builder.ToString();
            }

            
else
            
{
                
return GetEnumDes(type, enumValue.ToString());
            }

        }


        
/// <summary>
        
/// 获取某一Enum类型值的解释
        
/// </summary>
        
/// <param name="type"></param>
        
/// <param name="value"></param>
        
/// <returns></returns>

        private static string GetEnumDes(Type type, string value)
        
{
            
string xquery = "/translation/enum/" + type.FullName + "/" + value;
            XmlNode node 
= content.SelectSingleNode(xquery);
            
if (node != null)
                
return node.InnerText;
            
else
                
return value;
        }


        
/// <summary>
        
/// 翻译指定值
        
/// </summary>
        
/// <param name="obj"></param>
        
/// <returns></returns>

        public static string GetValueDescription(object obj)
        
{
            
return GetValueDescription("default", obj);
        }


        
/// <summary>
        
/// 在指定组中翻译指定值
        
/// </summary>
        
/// <param name="group"></param>
        
/// <param name="obj"></param>
        
/// <returns></returns>

        public static string GetValueDescription(string group, object obj)
        
{
            
if (obj == null)
                
return "null";

            
string xquery = "/translation/description[@group='" + group + "']/add[@key='" + obj.ToString() + "']/@value";
            XmlNode node 
= content.SelectSingleNode(xquery);
            
if (node == null)
                
return obj.ToString();
            
else
                
return node.Value;
        }

    }


在这个对象使用前需要使用 Configure方法来加载xml配置文件, 默认的配置文件名称为translation.config。转换对象使用单例模式,使用了一个 FileSystemWatcher对象来监视XML文件,如果XML有变化,则从新加载。查询XML使用了XPath表达式。

然后即可使用
GetEnumDescription和 GetValueDescription方法来翻译枚举和标识了。如果没有找到可以翻译的值,则会返回对象的ToString方法的返回值。

示例XML配置:

<? xml version="1.0" encoding="utf-8"  ?>
< translation >
  
< enum >
    
<!-- 此出要用枚举的全名 -->
    
< Library .UserType >
      
< Unknow > 未知 </ Unknow >
      
< AfterPayUser > 后付费用户 </ AfterPayUser >
      
< BeforePayUser > 预付费用户 </ BeforePayUser >
    
</ Library.UserType >
  
</ enum >

  
< description  group ="default" >
    
< add  key ="FileErrorl"  value ="文件已损坏"   />
  
</ description >

  
< description  group ="skin" >
    
< add  key ="Default"  value ="默认皮肤"   />
  
</ description >

  
< description  group ="topic" >
    
< add  key ="space"  value ="&lt;span class='red'&gt;您剩余的空间不足,请您删除部分文件。&lt;/span&gt;&lt;br/&gt;"   />
    
< add  key ="yue"  value ="&lt;span class='red'&gt;您的余额不足,请尽快充值。&lt;/span&gt;&lt;br /&gt;"   />
  
</ description >
</ translation >
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值