XML 2 Class [xml 转化为 序列化代码工具]

xml2class.jpg
    我经常要编写一些可序列化的类,用于存储配置,通过XML的属性标记可以很容易完成这些工作。但是大量的工作任务让我没有多少时间经常编写些‘体力代码’,于是就考虑如何简化这个工作。

    那么XML文件是最终的结构,那么能否从XML结构通过某种工具还原为原始的序列化类代码呢?答案是肯定的。

例如:
一个简单的XML 的描述:

None.gif < Test  x ="100.01"  y ="199.202"   />

它对应的序列化代码为:

None.gif [Serializable]
None.gif
public   class  Test
ExpandedBlockStart.gifContractedBlock.gif
dot.gif {
InBlock.gif 
protected double _x;
InBlock.gif 
protected double _y;
InBlock.gif [XmlAttribute()]
InBlock.gif 
public double X
ExpandedSubBlockStart.gifContractedSubBlock.gif 
dot.gif{
ExpandedSubBlockStart.gifContractedSubBlock.gif  
get dot.gif{return this._x;}
ExpandedSubBlockStart.gifContractedSubBlock.gif  
set dot.gif{this._x=value;}
ExpandedSubBlockEnd.gif }

InBlock.gif [XmlAttribute()]
InBlock.gif 
public double Y
ExpandedSubBlockStart.gifContractedSubBlock.gif 
dot.gif{
ExpandedSubBlockStart.gifContractedSubBlock.gif  
get dot.gif{return this._y;}
ExpandedSubBlockStart.gifContractedSubBlock.gif  
set dot.gif{this._y=value;}
ExpandedSubBlockEnd.gif }

ExpandedBlockEnd.gif}

None.gif

一个带集合的XML代码:

None.gif < Object  Name ="MyObject" >
None.gif 
< Fields >
None.gif  
< Field  Name ="Title" >
None.gif   
< Values >
None.gif    
< Value  Name ="ID"  PrimaryKey ="true" />
None.gif    
< Value  Name ="FirstName"  Unique ="false" />
None.gif    
< Value  Name ="LastName"  Unique ="false"  Indexed ="true" />
None.gif   
</ Values >
None.gif  
</ Field >
None.gif 
</ Fields >
None.gif 
< Methods >
None.gif  
< Method  Name ="Add" >
None.gif   
< Params >
None.gif    
< Param  Name ="X"  value ="1" />
None.gif    
< Param  Name ="Y"  value ="2" />
None.gif   
</ Params >
None.gif  
</ Method >
None.gif 
</ Methods >
None.gif
</ Object >

它对应的序列化代码为:

None.gif [Serializable]
None.gif
public   class  Param
ExpandedBlockStart.gifContractedBlock.gif
dot.gif {
InBlock.gif 
protected int _value;
InBlock.gif 
protected string _name;
InBlock.gif [XmlAttribute()]
InBlock.gif 
public int Value
ExpandedSubBlockStart.gifContractedSubBlock.gif 
dot.gif{
ExpandedSubBlockStart.gifContractedSubBlock.gif  
get dot.gif{return this._value;}
ExpandedSubBlockStart.gifContractedSubBlock.gif  
set dot.gif{this._value=value;}
ExpandedSubBlockEnd.gif }

InBlock.gif [XmlAttribute()]
InBlock.gif 
public string Name
ExpandedSubBlockStart.gifContractedSubBlock.gif 
dot.gif{
ExpandedSubBlockStart.gifContractedSubBlock.gif  
get dot.gif{return this._name;}
ExpandedSubBlockStart.gifContractedSubBlock.gif  
set dot.gif{this._name=value;}
ExpandedSubBlockEnd.gif }

ExpandedBlockEnd.gif}

None.gif
None.gif[Serializable]
None.gif
public   class  Object
ExpandedBlockStart.gifContractedBlock.gif
dot.gif {
InBlock.gif 
protected string _name;
InBlock.gif 
protected ArrayList _fields;
InBlock.gif 
protected ArrayList _methods;
InBlock.gif [XmlAttribute()]
InBlock.gif 
public string Name
ExpandedSubBlockStart.gifContractedSubBlock.gif 
dot.gif{
ExpandedSubBlockStart.gifContractedSubBlock.gif  
get dot.gif{return this._name;}
ExpandedSubBlockStart.gifContractedSubBlock.gif  
set dot.gif{this._name=value;}
ExpandedSubBlockEnd.gif }

InBlock.gif [XmlArray()]
InBlock.gif [XmlArrayItem(
typeof(Field))]
InBlock.gif 
public ArrayList Fields
ExpandedSubBlockStart.gifContractedSubBlock.gif 
dot.gif{
ExpandedSubBlockStart.gifContractedSubBlock.gif  
get dot.gif{return this._fields;}
ExpandedSubBlockEnd.gif }

InBlock.gif [XmlArray()]
InBlock.gif [XmlArrayItem(
typeof(Method))]
InBlock.gif 
public ArrayList Methods
ExpandedSubBlockStart.gifContractedSubBlock.gif 
dot.gif{
ExpandedSubBlockStart.gifContractedSubBlock.gif  
get dot.gif{return this._methods;}
ExpandedSubBlockEnd.gif }

InBlock.gif 
public Object()
ExpandedSubBlockStart.gifContractedSubBlock.gif 
dot.gif{
InBlock.gif  
this._fields=new ArrayList();
InBlock.gif  
this._methods=new ArrayList();
ExpandedSubBlockEnd.gif }

ExpandedBlockEnd.gif}

None.gif
None.gif[Serializable]
None.gif
public   class  Field
ExpandedBlockStart.gifContractedBlock.gif
dot.gif {
InBlock.gif 
protected string _name;
InBlock.gif 
protected ArrayList _values;
InBlock.gif [XmlAttribute()]
InBlock.gif 
public string Name
ExpandedSubBlockStart.gifContractedSubBlock.gif 
dot.gif{
ExpandedSubBlockStart.gifContractedSubBlock.gif  
get dot.gif{return this._name;}
ExpandedSubBlockStart.gifContractedSubBlock.gif  
set dot.gif{this._name=value;}
ExpandedSubBlockEnd.gif }

InBlock.gif [XmlArray()]
InBlock.gif [XmlArrayItem(
typeof(Value))]
InBlock.gif 
public ArrayList Values
ExpandedSubBlockStart.gifContractedSubBlock.gif 
dot.gif{
ExpandedSubBlockStart.gifContractedSubBlock.gif  
get dot.gif{return this._values;}
ExpandedSubBlockEnd.gif }

InBlock.gif 
public Field()
ExpandedSubBlockStart.gifContractedSubBlock.gif 
dot.gif{
InBlock.gif  
this._values=new ArrayList();
ExpandedSubBlockEnd.gif }

ExpandedBlockEnd.gif}

None.gif
None.gif[Serializable]
None.gif
public   class  Value
ExpandedBlockStart.gifContractedBlock.gif
dot.gif {
InBlock.gif 
protected string _name;
InBlock.gif 
protected bool _unique;
InBlock.gif 
protected bool _primaryKey;
InBlock.gif 
protected bool _indexed;
InBlock.gif [XmlAttribute()]
InBlock.gif 
public string Name
ExpandedSubBlockStart.gifContractedSubBlock.gif 
dot.gif{
ExpandedSubBlockStart.gifContractedSubBlock.gif  
get dot.gif{return this._name;}
ExpandedSubBlockStart.gifContractedSubBlock.gif  
set dot.gif{this._name=value;}
ExpandedSubBlockEnd.gif }

InBlock.gif [XmlAttribute()]
InBlock.gif 
public bool Unique
ExpandedSubBlockStart.gifContractedSubBlock.gif 
dot.gif{
ExpandedSubBlockStart.gifContractedSubBlock.gif  
get dot.gif{return this._unique;}
ExpandedSubBlockStart.gifContractedSubBlock.gif  
set dot.gif{this._unique=value;}
ExpandedSubBlockEnd.gif }

InBlock.gif [XmlAttribute()]
InBlock.gif 
public bool PrimaryKey
ExpandedSubBlockStart.gifContractedSubBlock.gif 
dot.gif{
ExpandedSubBlockStart.gifContractedSubBlock.gif  
get dot.gif{return this._primaryKey;}
ExpandedSubBlockStart.gifContractedSubBlock.gif  
set dot.gif{this._primaryKey=value;}
ExpandedSubBlockEnd.gif }

InBlock.gif [XmlAttribute()]
InBlock.gif 
public bool Indexed
ExpandedSubBlockStart.gifContractedSubBlock.gif 
dot.gif{
ExpandedSubBlockStart.gifContractedSubBlock.gif  
get dot.gif{return this._indexed;}
ExpandedSubBlockStart.gifContractedSubBlock.gif  
set dot.gif{this._indexed=value;}
ExpandedSubBlockEnd.gif }

ExpandedBlockEnd.gif}

None.gif
None.gif[Serializable]
None.gif
public   class  Method
ExpandedBlockStart.gifContractedBlock.gif
dot.gif {
InBlock.gif 
protected string _name;
InBlock.gif 
protected ArrayList _params;
InBlock.gif [XmlAttribute()]
InBlock.gif 
public string Name
ExpandedSubBlockStart.gifContractedSubBlock.gif 
dot.gif{
ExpandedSubBlockStart.gifContractedSubBlock.gif  
get dot.gif{return this._name;}
ExpandedSubBlockStart.gifContractedSubBlock.gif  
set dot.gif{this._name=value;}
ExpandedSubBlockEnd.gif }

InBlock.gif [XmlArray()]
InBlock.gif [XmlArrayItem(
typeof(Param))]
InBlock.gif 
public ArrayList Params
ExpandedSubBlockStart.gifContractedSubBlock.gif 
dot.gif{
ExpandedSubBlockStart.gifContractedSubBlock.gif  
get dot.gif{return this._params;}
ExpandedSubBlockEnd.gif }

InBlock.gif 
public Method()
ExpandedSubBlockStart.gifContractedSubBlock.gif 
dot.gif{
InBlock.gif  
this._params=new ArrayList();
ExpandedSubBlockEnd.gif }

ExpandedBlockEnd.gif}

可以看到,比较复杂的XML代码的序列化类编码工作量是比较麻烦而且单调的。

那么如何才能将XML生成这样的逆向代码呢?

1、 递归遍历XML Node
2、 登记实体类的名称,类似“public class Method”
3、 登记所有属性的信息,解析属性类型,类似“protected string _name;”

None.gif //  检查是否为 boolean
None.gif
if  ((val  ==   " true " ||  (val  ==   " false " ))
ExpandedBlockStart.gifContractedBlock.gif
dot.gif {
InBlock.gif    ptype 
= "bool";
ExpandedBlockEnd.gif}

None.gif
None.gif
//  检查是否为 int ,如果带小数,则表示为 double
None.gif
if  (Char.IsDigit(val,  0 ))
ExpandedBlockStart.gifContractedBlock.gif
dot.gif {
InBlock.gif    ptype 
= "int";
InBlock.gif    
if (val.IndexOf("."!= -1)
ExpandedSubBlockStart.gifContractedSubBlock.gif    
dot.gif{
InBlock.gif        ptype 
= "double";
ExpandedSubBlockEnd.gif    }

ExpandedBlockEnd.gif}

None.gif
None.gif

4、 登记集合类的名称,用于创建类似“[XmlArrayItem(typeof(Param))]”的代码
5、 输出代码

实现这些步骤的代码:

None.gif using  System;
None.gif
using  System.Collections.Generic;
None.gif
using  System.Text;
None.gif
using  System.Collections;
None.gif
using  System.Xml;
None.gif
using  System.Windows.Forms;
None.gif
None.gif
namespace  Infotech.Config.Tools.Xml2Class
ExpandedBlockStart.gifContractedBlock.gif
dot.gif {
InBlock.gif    
public sealed class ClassInfo
ExpandedSubBlockStart.gifContractedSubBlock.gif    
dot.gif{
InBlock.gif        
public string name;
InBlock.gif        
public Hashtable properties; //保存属性
InBlock.gif
        public ArrayList collections; //保存集合名
InBlock.gif
        public Hashtable collectionTypes; //保存集合对应类型
InBlock.gif

InBlock.gif        
public ClassInfo(string name)
ExpandedSubBlockStart.gifContractedSubBlock.gif        
dot.gif{
InBlock.gif            
this.name = name;
InBlock.gif            properties 
= new Hashtable();
InBlock.gif            collections 
= new ArrayList();
InBlock.gif            collectionTypes 
= new Hashtable();
ExpandedSubBlockEnd.gif        }

ExpandedSubBlockEnd.gif    }

InBlock.gif
ExpandedSubBlockStart.gifContractedSubBlock.gif    
/**//// <summary>
InBlock.gif    
/// XML 转 Class 
InBlock.gif    
/// </summary>
InBlock.gif    
/// <example>
InBlock.gif    
/// <code escape="true">
InBlock.gif    
/// Example 1:
InBlock.gif    
/// <Database Name="MyDB">
InBlock.gif    
///  <Tables>
InBlock.gif    
///   <Table Name="Person">
InBlock.gif    
///    <Fields>
InBlock.gif    
///     <Field Name="ID" PrimaryKey="true"/>
InBlock.gif    
///     <Field Name="FirstName" Unique="false"/>
InBlock.gif    
///     <Field Name="LastName" Unique="false" Indexed="true"/>
InBlock.gif    
///    </Fields>
InBlock.gif    
///   </Table>
InBlock.gif    
///  </Tables>
InBlock.gif    
/// </Database>
InBlock.gif    
/// Example 2:
InBlock.gif    
/// <ComplexNumber Real="12.34" Imaginary="45.67"/>
InBlock.gif    
/// </code>
ExpandedSubBlockEnd.gif    
/// </example>

InBlock.gif    public class ClassGenerator
ExpandedSubBlockStart.gifContractedSubBlock.gif    
dot.gif{
InBlock.gif        
protected Hashtable classInfoList;
InBlock.gif
InBlock.gif        
public ClassGenerator()
ExpandedSubBlockStart.gifContractedSubBlock.gif        
dot.gif{
InBlock.gif            classInfoList 
= new Hashtable();
ExpandedSubBlockEnd.gif        }

InBlock.gif
InBlock.gif        
public string Generate(string src)
ExpandedSubBlockStart.gifContractedSubBlock.gif        
dot.gif{
InBlock.gif            classInfoList.Clear();
InBlock.gif            
string dest = "";
InBlock.gif
InBlock.gif            XmlDocument doc 
= new XmlDocument();
InBlock.gif            
try
ExpandedSubBlockStart.gifContractedSubBlock.gif            
dot.gif{
InBlock.gif                doc.LoadXml(src);
ExpandedSubBlockEnd.gif            }

InBlock.gif            
catch (Exception ex)
ExpandedSubBlockStart.gifContractedSubBlock.gif            
dot.gif{
InBlock.gif                MessageBox.Show(ex.Message);
InBlock.gif                
return "";
ExpandedSubBlockEnd.gif            }

InBlock.gif            XmlNode root 
= doc.DocumentElement;
InBlock.gif            ProcessClass(root);
InBlock.gif            dest 
= EmitCode();
InBlock.gif
InBlock.gif            
return dest;
ExpandedSubBlockEnd.gif        }

InBlock.gif
InBlock.gif        
protected void ProcessClass(XmlNode node)
ExpandedSubBlockStart.gifContractedSubBlock.gif        
dot.gif{
InBlock.gif            
string className = node.Name;
InBlock.gif            ClassInfo ci;
InBlock.gif
InBlock.gif            
if (classInfoList.Contains(className))
ExpandedSubBlockStart.gifContractedSubBlock.gif            
dot.gif{
InBlock.gif                ci 
= (ClassInfo)classInfoList[className];
ExpandedSubBlockEnd.gif            }

InBlock.gif            
else
ExpandedSubBlockStart.gifContractedSubBlock.gif            
dot.gif{
InBlock.gif                ci 
= new ClassInfo(className);
InBlock.gif                classInfoList[className] 
= ci;
ExpandedSubBlockEnd.gif            }

InBlock.gif
InBlock.gif            
foreach (XmlAttribute attr in node.Attributes)
ExpandedSubBlockStart.gifContractedSubBlock.gif            
dot.gif{
InBlock.gif                
string name = attr.Name;
InBlock.gif                
string val = attr.Value.ToLower();
InBlock.gif
InBlock.gif                
string ptype = "string";
InBlock.gif
InBlock.gif                
// 检查属性是否存在
InBlock.gif
                if (!ci.properties.Contains(name))
ExpandedSubBlockStart.gifContractedSubBlock.gif                
dot.gif{
InBlock.gif                    
// 检查是否为 boolean
InBlock.gif
                    if ((val == "true"|| (val == "false"))
ExpandedSubBlockStart.gifContractedSubBlock.gif                    
dot.gif{
InBlock.gif                        ptype 
= "bool";
ExpandedSubBlockEnd.gif                    }

InBlock.gif
InBlock.gif                    
// 检查是否为 int ,如果带小数则表示为 double
InBlock.gif
                    if (Char.IsDigit(val, 0))
ExpandedSubBlockStart.gifContractedSubBlock.gif                    
dot.gif{
InBlock.gif                        ptype 
= "int";
InBlock.gif                        
if (val.IndexOf("."!= -1)
ExpandedSubBlockStart.gifContractedSubBlock.gif                        
dot.gif{
InBlock.gif                            ptype 
= "double";
ExpandedSubBlockEnd.gif                        }

ExpandedSubBlockEnd.gif                    }

InBlock.gif                    ci.properties[name] 
= ptype;
ExpandedSubBlockEnd.gif                }

InBlock.gif
InBlock.gif                
foreach (XmlNode childNode in node.ChildNodes)
ExpandedSubBlockStart.gifContractedSubBlock.gif                
dot.gif{
InBlock.gif                    
if (!ci.collections.Contains(childNode.Name))
ExpandedSubBlockStart.gifContractedSubBlock.gif                    
dot.gif{
InBlock.gif                        ci.collections.Add(childNode.Name);
InBlock.gif                        
foreach (XmlNode grandchildNode in childNode.ChildNodes)
ExpandedSubBlockStart.gifContractedSubBlock.gif                        
dot.gif{
InBlock.gif                            
//增加集合类型
InBlock.gif
                            if (!ci.collectionTypes.Contains(childNode.Name))
ExpandedSubBlockStart.gifContractedSubBlock.gif                            
dot.gif{
InBlock.gif                                ci.collectionTypes[childNode.Name] 
= grandchildNode.Name;
ExpandedSubBlockEnd.gif                            }

InBlock.gif
//递归调用
InBlock.gif
                            ProcessClass(grandchildNode);
ExpandedSubBlockEnd.gif                        }

ExpandedSubBlockEnd.gif                    }

ExpandedSubBlockEnd.gif                }

ExpandedSubBlockEnd.gif            }

ExpandedSubBlockEnd.gif        }

InBlock.gif
InBlock.gif        
protected string EmitCode()
ExpandedSubBlockStart.gifContractedSubBlock.gif        
dot.gif{
InBlock.gif            StringBuilder sb 
= new StringBuilder();
InBlock.gif
InBlock.gif            
foreach (DictionaryEntry entry in classInfoList)
ExpandedSubBlockStart.gifContractedSubBlock.gif            
dot.gif{
InBlock.gif                ClassInfo ci 
= (ClassInfo)entry.Value;
InBlock.gif                
string cname = ci.name.ToUpper()[0+ ci.name.Substring(1);
InBlock.gif                sb.Append(
"//由 xml2Class 工具生成");
InBlock.gif                sb.Append(
"[Serializable]\r\n");
InBlock.gif                sb.Append(
"public class " + cname + "\r\n");
InBlock.gif                sb.Append(
"{\r\n");
InBlock.gif
InBlock.gif                
//创建属性变量
InBlock.gif
                foreach (DictionaryEntry prop in ci.properties)
ExpandedSubBlockStart.gifContractedSubBlock.gif                
dot.gif{
InBlock.gif                    
string pname = (string)prop.Key;
InBlock.gif                    
string ptype = (string)prop.Value;
InBlock.gif                    pname 
= pname.ToLower()[0+ pname.Substring(1);
InBlock.gif                    sb.Append(
"\tprotected " + ptype + " _" + pname + ";\r\n");
ExpandedSubBlockEnd.gif                }

InBlock.gif                
//创建集合变量
InBlock.gif
                foreach (string collName in ci.collections)
ExpandedSubBlockStart.gifContractedSubBlock.gif                
dot.gif{
InBlock.gif                    
string name = collName.ToLower()[0+ collName.Substring(1);
InBlock.gif                    sb.Append(
"\tprotected ArrayList _" + name + ";\r\n");
ExpandedSubBlockEnd.gif                }

InBlock.gif
InBlock.gif                
//创建属性
InBlock.gif
                foreach (DictionaryEntry prop in ci.properties)
ExpandedSubBlockStart.gifContractedSubBlock.gif                
dot.gif{
InBlock.gif                    
string pname = (string)prop.Key;
InBlock.gif                    
string ptype = (string)prop.Value;
InBlock.gif                    pname 
= pname.ToLower()[0+ pname.Substring(1);
InBlock.gif                    
string sname = pname.ToUpper()[0+ pname.Substring(1);
InBlock.gif                    sb.Append(
"\t[XmlAttribute()]\r\n");
InBlock.gif                    sb.Append(
"\tpublic " + ptype + " " + sname + "\r\n");
InBlock.gif                    sb.Append(
"\t{\r\n");
InBlock.gif                    sb.Append(
"\t\tget {return this._" + pname + ";}\r\n");
InBlock.gif                    sb.Append(
"\t\tset {this._" + pname + "=value;}\r\n");
InBlock.gif                    sb.Append(
"\t}\r\n");
ExpandedSubBlockEnd.gif                }

InBlock.gif
InBlock.gif                
//创建集合
InBlock.gif
                foreach (string collName in ci.collections)
ExpandedSubBlockStart.gifContractedSubBlock.gif                
dot.gif{
InBlock.gif                    
string name = collName.ToUpper()[0+ collName.Substring(1);
InBlock.gif                    
string collNameSmall = collName.ToLower()[0+ collName.Substring(1);
InBlock.gif                    sb.Append(
"\t[XmlArray()]\r\n\t[XmlArrayItem(typeof(" + ci.collectionTypes[name] + "))]\r\n");
InBlock.gif                    sb.Append(
"\tpublic ArrayList " + name + "\r\n");
InBlock.gif                    sb.Append(
"\t{\r\n");
InBlock.gif                    sb.Append(
"\t\tget {return this._" + collNameSmall + ";}\r\n");
InBlock.gif                    sb.Append(
"\t}\r\n");
ExpandedSubBlockEnd.gif                }

InBlock.gif
InBlock.gif                
// 创建构造函数,当有子集合才需要
InBlock.gif
                if (ci.collections.Count > 0)
ExpandedSubBlockStart.gifContractedSubBlock.gif                
dot.gif{
InBlock.gif                    sb.Append(
"\tpublic " + cname + "()\r\n");
InBlock.gif                    sb.Append(
"\t{\r\n");
InBlock.gif                    
foreach (string collName in ci.collections)
ExpandedSubBlockStart.gifContractedSubBlock.gif                    
dot.gif{
InBlock.gif                        
string name = collName.ToLower()[0+ collName.Substring(1);
InBlock.gif                        sb.Append(
"\t\tthis._" + name + "=new ArrayList();\r\n");
ExpandedSubBlockEnd.gif                    }

InBlock.gif                    sb.Append(
"\t}\r\n");
ExpandedSubBlockEnd.gif                }

InBlock.gif                sb.Append(
"}\r\n\r\n");
ExpandedSubBlockEnd.gif            }

InBlock.gif            
return sb.ToString();
ExpandedSubBlockEnd.gif        }

ExpandedSubBlockEnd.gif    }

ExpandedBlockEnd.gif}

None.gif
None.gif

有些人喜欢看代码,了解思路;而有些人则喜欢直接使用工具,所以我希望这个工具对大家有所帮助,并提供了代码和执行程序的下载。

下载地址:

/Files/Chinasf/Xml2Class.rar

随飞 2006年6月10日星期六

转载于:https://www.cnblogs.com/Chinasf/articles/xml2class.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值