如何动态根据一个业务实体类型创建XSD架构文件
创始人
2024-04-27 11:00:41
0

目前该功能仅仅是一个原型,还有待细化改进。例如在实体的成员上用一些特定的Attribute标明该成员要被保存的形态。

创建XSD架构文件***部分:业务实体类

(作为演示目的,我将所有的类型定义在一个文件里,同时每个类都只有少量简单的属性成员)

此处特别注意的是,Order这个类是很复杂的,它包含了一系列的OrderItem,而OrderItem又包含了Product对象。

  1. using System;  
  2. using System.Collections.Generic;  
  3. using System.Text;   
  4.  
  5. namespace DataEntities  
  6. {  
  7.     public class Order  
  8.     {  
  9.         public int OrderID { get; set; }  
  10.         public string CustomerID { get; set; }  
  11.         public int EmployeeID { get; set; }  
  12.         public DateTime OrderDate { get; set; }  
  13.         public List OrderItems { get; set; }   
  14.  
  15.         public override string ToString()  
  16.         {  
  17.             StringBuilder sb = new StringBuilder();  
  18.             sb.AppendFormat("\t{0}\t{1}\t{2}\t{3}", OrderID, CustomerID, EmployeeID, OrderDate);  
  19.             sb.AppendLine();  
  20.             foreach (var item in OrderItems)  
  21.             {  
  22.                 sb.AppendFormat("\t\t{0}\t{1}\t{2}\n", item.Product.ProductName, item.UnitPrice, item.Quantity);  
  23.             }  
  24.             return sb.ToString();  
  25.         }   
  26.  
  27.     }   
  28.     public class OrderItem   
  29.     {  
  30.         public int OrderId { get; set; }  
  31.         public Product Product { get; set; }  
  32.         public decimal UnitPrice { get; set; }  
  33.         public decimal Quantity { get; set; }  
  34.  
  35.     }  
  36.     public class Product   
  37.     {  
  38.         public int ProductId { get; set; }  
  39.         public string ProductName { get; set; }  
  40.  
  41.     }  

创建XSD架构文件第二部分:生成XSD的工具类(Utility.cs)

  1. using System;  
  2. using System.Xml.Linq;  
  3. using System.Collections;  
  4. using System.Xml;  
  5.  
  6. namespace XMLDatabase  
  7. {  
  8.     public class Utility  
  9.     {  
  10.         ///  
  11.         /// 使用指定类型生成一个架构文件  
  12.         /// 
  13.  
  14.         ///  name="T"> 
  15.         public static void XsdGenerate(XmlWriter xw) {  
  16.             Type t = typeof(T);  
  17.  
  18.             XNamespace xn = "http://www.w3.org/2001/XMLSchema";  
  19.             XDocument doc = new XDocument(  
  20.                 new XDeclaration("1.0", "utf-8", "yes"),  
  21.                 new XElement(xn + "schema",  
  22.                     new XAttribute("elementFormDefault", "qualified"),  
  23.                     new XAttribute(XNamespace.Xmlns + "xs", "http://www.w3.org/2001/XMLSchema"),  
  24.                     new XElement(xn+"element",  
  25.                         new XAttribute("name","Table"),  
  26.                         new XAttribute("nillable","true"),  
  27.                         new XAttribute("type","Table"))  
  28.                     ));  
  29.  
  30.  
  31.             XElement tableElement = new XElement(xn + "complexType",  
  32.                 new XAttribute("name", "Table"));  
  33.  
  34.             tableElement.Add(  
  35.                 new XElement(xn + "sequence",  
  36.                     new XElement(xn + "element",  
  37.                         new XAttribute("minOccurs", "0"),  
  38.                         new XAttribute("maxOccurs", "unbounded"),  
  39.                         new XAttribute("name","Row"),  
  40.                         new XAttribute("type",t.Name)  
  41.                         )),  
  42.                 new XElement(xn + "attribute",  
  43.                     new XAttribute("name", "CreateTime"),  
  44.                     new XAttribute("type", "xs:string"))  
  45.                         );  
  46.  
  47.             doc.Root.Add(tableElement);  
  48.  
  49.             CreateComplexType(t, doc.Root);  
  50.             doc.Save(xw);  
  51.  
  52.         }  
  53.  
  54.  
  55.         private static void CreateComplexType(Type t,XElement root) {  
  56.  
  57.             XNamespace xn = root.GetNamespaceOfPrefix("xs");  
  58.             XElement temp = new XElement(  
  59.                 xn + "complexType",  
  60.                 new XAttribute("name", t.Name));  
  61.             #region 循环所有属性  
  62.  
  63.             foreach (var p in t.GetProperties())//循环所有属性  
  64.             {  
  65.                 Type ppType = p.PropertyType;  
  66.                 string fullType = pType.FullName;  
  67.  
  68.                 //这里仍然是分几种情况  
  69.                 if (!GeneralType.Contains(fullType))  
  70.                 {  
  71.  
  72.                     var seqelement = temp.Element(xn + "sequence");  
  73.                     if (seqelement == null)  
  74.                     {  
  75.                         seqelement = new XElement(xn + "sequence");  
  76.                         temp.AddFirst(seqelement);  
  77.                     }  
  78.  
  79.                     if (pType.IsEnum)//如果是枚举  
  80.                     {  
  81.                         seqelement.Add(  
  82.                             new XElement(  
  83.                                 xn + "element",  
  84.                                 new XAttribute("minOccurs", "0"),  
  85.                                 new XAttribute("maxOccurs", "1"),  
  86.                                 new XAttribute("name", p.Name),  
  87.                                 new XAttribute("type", pType.Name)));  
  88.  
  89.                         XElement enumElement = new XElement(  
  90.                             xn + "complexType",  
  91.                             new XAttribute("name", pType.Name),  
  92.                             new XElement(xn + "attribute",  
  93.                                 new XAttribute("name", "Enum"),  
  94.                                 new XAttribute("type", "xs:string")));  
  95.                         root.Add(enumElement);  
  96.  
  97.                     }  
  98.                     else if (pType.GetInterface(typeof(IList).FullName) != null && pType.IsGenericType)  
  99.                         //如果是集合,并且是泛型集合  
  100.                     {  
  101.  
  102.                         Type itemType = pType.GetGenericArguments()[0];  
  103.                         seqelement.Add(  
  104.                             new XElement(  
  105.                                 xn + "element",  
  106.                                 new XAttribute("minOccurs", "0"),  
  107.                                 new XAttribute("maxOccurs", "1"),  
  108.                                 new XAttribute("name", p.Name),  
  109.                                 new XAttribute("type", "ArrayOf"+p.Name)));  
  110.  
  111.                         XElement arrayElement = new XElement(  
  112.                             xn + "complexType",  
  113.                             new XAttribute("name", "ArrayOf" + p.Name),  
  114.                             new XElement(xn + "sequence",  
  115.                                 new XElement(xn + "element",  
  116.                                     new XAttribute("minOccurs", "0"),  
  117.                                     new XAttribute("maxOccurs", "unbounded"),  
  118.                                     new XAttribute("name", itemType.Name),  
  119.                                     new XAttribute("type", itemType.Name))));  
  120.  
  121.                         root.Add(arrayElement);  
  122.  
  123.                         CreateComplexType(itemType, root);  
  124.  
  125.                     }  
  126.                     else if (pType.IsClass || pType.IsValueType)  
  127.                     {  
  128.                         seqelement.Add(  
  129.                             new XElement(  
  130.                                 xn + "element",  
  131.                                 new XAttribute("minOccurs", "0"),  
  132.                                 new XAttribute("maxOccurs", "1"),  
  133.                                 new XAttribute("name", p.Name),  
  134.                                 new XAttribute("type", pType.Name)));  
  135.  
  136.                         CreateComplexType(pType, root);  
  137.                     }  
  138.                 }  
  139.                 else  
  140.                 {  
  141.                     //这种情况最简单,属性为标准内置类型,直接作为元素的Attribute即可  
  142.                     temp.Add(  
  143.                         new XElement(xn + "attribute",  
  144.                             new XAttribute("name", p.Name),  
  145.                             new XAttribute("type", GeneralType.ConvertXSDType(pType.FullName))));  
  146.  
  147.                 }  
  148.  
  149.             }  
  150.             #endregion  
  151.  
  152.             temp.Add(new XElement(xn + "attribute",  
  153.                 new XAttribute("name", "TypeName"),  
  154.                 new XAttribute("type", "xs:string")));  
  155.  
  156.             root.Add(temp);  
  157.         }  
  158.  
  159.     }  

创建XSD架构文件第三部分:辅助类型(GeneralType.cs).

这个类型中有一个方法可以将业务实体类型成员属性的类型转换为XSD中 的类型。

  1. using System;  
  2. using System.Collections.Generic;  
  3. using System.Text;  
  4.  
  5. namespace XMLDatabase  
  6. {  
  7.     public class GeneralType  
  8.     {  
  9.         private static readonly List generalTypes = new List()  
  10.         {  
  11.             "System.Byte",//typeof(byte).FullName,  
  12.             "System.SByte",//typeof(sbyte).FullName,  
  13.             "System.Int16",//typeof(short).FullName,  
  14.             "System.UInt16",//typeof(ushort).FullName,  
  15.             "System.Int32",//typeof(int).FullName,  
  16.             "System.UInt32",//typeof(uint).FullName,  
  17.             "System.Int64",//typeof(long).FullName,  
  18.             "System.UInt64",//typeof(ulong).FullName,  
  19.             "System.Double",//typeof(double).FullName,  
  20.             "System.Decimal",//typeof(decimal).FullName,  
  21.             "System.Single",//typeof(float).FullName,  
  22.             "System.Char",//typeof(char).FullName,  
  23.             "System.Boolean",//typeof(bool).FullName,  
  24.             "System.String",//typeof(string).FullName,  
  25.             "System.DateTime"//typeof(DateTime).FullName  
  26.         };  
  27.  
  28.  
  29.         ///  
  30.         /// 判断当前给定类型是否为默认的数据类型  
  31.         /// 
  32.  
  33.         ///  name="fullType"> 
  34.         ///  
  35.         public static bool Contains(string fullType)  
  36.         {  
  37.             return generalTypes.Contains(fullType);  
  38.         }  
  39.  
  40.  
  41.         public static string ConvertXSDType(string fullType)  
  42.         {  
  43.             switch (fullType)  
  44.             {  
  45.                 case "System.String":  
  46.                     return "xs:string";  
  47.                 case "System.Int32":  
  48.                     return "xs:int";  
  49.                 case "System.DateTime":  
  50.                     return "xs:dateTime";  
  51.                 case "System.Boolean":  
  52.                     return "xs:boolean";  
  53.                 case "System.Single":  
  54.                     return "xs:float";  
  55.                 case "System.Byte":  
  56.                     return "xs:byte";  
  57.                 case "System.SByte":  
  58.                     return "xs:unsignedByte";  
  59.                 case "System.Int16":  
  60.                     return "xs:short";  
  61.                 case "System.UInt16":  
  62.                     return "xs:unsignedShort";  
  63.                 case "System.UInt32":  
  64.                     return "xs:unsignedInt";  
  65.                 case "System.Int64":  
  66.                     return "xs:long";  
  67.                 case "System.UInt64":  
  68.                     return "xs:unsignedLong";  
  69.                 case "System.Double":  
  70.                     return "xs:double";  
  71.                 case "System.Decimal":  
  72.                     return "xs:decimal";  
  73.  
  74.                 default:  
  75.                     break;  
  76.             }  
  77.  
  78.             return string.Empty;  
  79.         }  
  80.           
  81.     }  

创建XSD架构文件第四部分:单元测试

  1. ///  
  2. ///XsdGenerate 的测试  
  3. ///
  4.  
  5. public void XsdGenerateTestHelper()  
  6. {  
  7.     XmlWriter xw = XmlWriter.Create("Order.xsd"); // TODO: 初始化为适当的值  
  8.     Utility.XsdGenerate(xw);  
  9.  
  10.     xw.Close();  

创建XSD架构文件第五部分: 生成的结果

  1.  version="1.0" encoding="utf-8" standalone="yes"?> 
  2.  elementFormDefault="qualified" xmlns:xs="http://www.w3.org/2001/XMLSchema"> 
  3.    name="Table" nillable="true" type="Table" /> 
  4.    name="Table"> 
  5.      
  6.        minOccurs="0" maxOccurs="unbounded" name="Row" type="Order" /> 
  7.      
  8.      name="CreateTime" type="xs:string" /> 
  9.    
  10.    name="ArrayOfOrderItems"> 
  11.      
  12.        minOccurs="0" maxOccurs="unbounded" name="OrderItem" type="OrderItem" /> 
  13.      
  14.    
  15.    name="Product"> 
  16.      name="ProductId" type="xs:int" /> 
  17.      name="ProductName" type="xs:string" /> 
  18.      name="TypeName" type="xs:string" /> 
  19.    
  20.    name="OrderItem"> 
  21.      
  22.        minOccurs="0" maxOccurs="1" name="Product" type="Product" /> 
  23.      
  24.      name="OrderId" type="xs:int" /> 
  25.      name="UnitPrice" type="xs:decimal" /> 
  26.      name="Quantity" type="xs:decimal" /> 
  27.      name="TypeName" type="xs:string" /> 
  28.    
  29.    name="Order"> 
  30.      
  31.        minOccurs="0" maxOccurs="1" name="OrderItems" type="ArrayOfOrderItems" /> 
  32.      
  33.      name="OrderID" type="xs:int" /> 
  34.      name="CustomerID" type="xs:string" /> 
  35.      name="EmployeeID" type="xs:int" /> 
  36.      name="OrderDate" type="xs:dateTime" /> 
  37.      name="TypeName" type="xs:string" /> 
  38.    
  39.  

创建XSD架构文件第六部分:合法的数据文件范例

  1.  version="1.0" encoding="utf-8"?> 
  2.  Name="Orders" CreateTime="2009/8/9 21:59:04"> 
  3.    TypeName="DataEntities.Order" OrderID="10249" CustomerID="ABCDEF" EmployeeID="1" OrderDate="2009-08-09T21:59:04.125+08:00"> 
  4.      
  5.        TypeName="DataEntities.OrderItem" OrderId="10249" UnitPrice="25" Quantity="4"> 
  6.          TypeName="DataEntities.Product" ProductId="1" ProductName="Pen" /> 
  7.        
  8.        TypeName="DataEntities.OrderItem" OrderId="10249" UnitPrice="2" Quantity="2000"> 
  9.          TypeName="DataEntities.Product" ProductId="1" ProductName="Car" /> 
  10.        
  11.      
  12.    
  13.    TypeName="DataEntities.Order" OrderID="10249" CustomerID="ABCDEF" EmployeeID="1" OrderDate="2009-08-10T07:29:51.546875+08:00"> 
  14.      
  15.        TypeName="DataEntities.OrderItem" OrderId="10249" UnitPrice="25" Quantity="4"> 
  16.          TypeName="DataEntities.Product" ProductId="1" ProductName="Pen" /> 
  17.        
  18.        TypeName="DataEntities.OrderItem" OrderId="10249" UnitPrice="2" Quantity="2000"> 
  19.          TypeName="DataEntities.Product" ProductId="1" ProductName="Car" /> 
  20.        
  21.      
  22.    
  23.    TypeName="DataEntities.Order" OrderID="10249" CustomerID="ABCDEF" EmployeeID="1" OrderDate="2009-08-10T07:30:13.375+08:00"> 
  24.      
  25.        TypeName="DataEntities.OrderItem" OrderId="10249" UnitPrice="25" Quantity="4"> 
  26.          TypeName="DataEntities.Product" ProductId="1" ProductName="Pen" /> 
  27.        
  28.        TypeName="DataEntities.OrderItem" OrderId="10249" UnitPrice="2" Quantity="2000"> 
  29.          TypeName="DataEntities.Product" ProductId="1" ProductName="Car" /> 
  30.        
  31.      
  32.    
  33.    TypeName="DataEntities.Order" OrderID="10249" CustomerID="ABCDEF" EmployeeID="1" OrderDate="2009-08-10T07:30:43.875+08:00"> 
  34.      
  35.        TypeName="DataEntities.OrderItem" OrderId="10249" UnitPrice="25" Quantity="4"> 
  36.          TypeName="DataEntities.Product" ProductId="1" ProductName="Pen" /> 
  37.        
  38.        TypeName="DataEntities.OrderItem" OrderId="10249" UnitPrice="2" Quantity="2000"> 
  39.          TypeName="DataEntities.Product" ProductId="1" ProductName="Car" /> 
  40.        
  41.      
  42.    
  43.  

【编辑推荐】

  1. .NET 4.0的ICustomQueryInterface新特性
  2. .NET Lambda表达式的函数式特性:索引示例
  3. .NET Lambda表达式的语义:字符串列表范例
  4. .NET 3.5扩展方法点评:优点与问题
  5. 各版本.NET委托的写法回顾

相关内容

热门资讯

如何允许远程连接到MySQL数... [[277004]]【51CTO.com快译】默认情况下,MySQL服务器仅侦听来自localhos...
如何利用交换机和端口设置来管理... 在网络管理中,总是有些人让管理员头疼。下面我们就将介绍一下一个网管员利用交换机以及端口设置等来进行D...
施耐德电气数据中心整体解决方案... 近日,全球能效管理专家施耐德电气正式启动大型体验活动“能效中国行——2012卡车巡展”,作为该活动的...
20个非常棒的扁平设计免费资源 Apple设备的平面图标PSD免费平板UI 平板UI套件24平图标Freen平板UI套件PSD径向平...
德国电信门户网站可实时显示全球... 德国电信周三推出一个门户网站,直观地实时提供其安装在全球各地的传感器网络检测到的网络攻击状况。该网站...
为啥国人偏爱 Mybatis,... 关于 SQL 和 ORM 的争论,永远都不会终止,我也一直在思考这个问题。昨天又跟群里的小伙伴进行...
《非诚勿扰》红人闫凤娇被曝厕所... 【51CTO.com 综合消息360安全专家提醒说,“闫凤娇”、“非诚勿扰”已经被黑客盯上成为了“木...
2012年第四季度互联网状况报... [[71653]]  北京时间4月25日消息,据国外媒体报道,全球知名的云平台公司Akamai Te...