自拍偷在线精品自拍偷,亚洲欧美中文日韩v在线观看不卡

.NET框架中的XML基礎類:xsd.exe

開發(fā) 后端
本文介紹了.NET框架中的XML基礎類。一種從 XSD 生成代碼的方法是以統(tǒng)一的方式對架構(gòu)對象模型 (SOM) 進行簡單的迭代,并直接根據(jù)該模型編寫代碼。這正是大量為克服 xsd.exe 工具局限而創(chuàng)建的代碼生成器所采取的方法。

.NET框架中的XML基礎類

一種從 XSD 生成代碼的方法是以統(tǒng)一的方式對架構(gòu)對象模型 (SOM) 進行簡單的迭代,并直接根據(jù)該模型編寫代碼。這正是大量為克服 xsd.exe 工具局限而創(chuàng)建的代碼生成器所采取的方法。不過,這需要付出相當大的努力以及編寫大量的代碼,因為我們應考慮 XSD 到 CLR 類型映射、XSD 類型繼承、XML 序列化特性等問題。掌握 SOM 也不是一件輕而易舉的事情。如果無須由我們自己來完成所有工作,而只需添加或修改 xsd.exe 工具的內(nèi)置代碼生成,難道不好嗎?

正像我前面所說的,但與普遍看法不同的是,xsd.exe 用于生成輸出的類就在 System.Xml.Serialization 命名空間中并被聲明為公共類,即使 xsd.exe 工具在某種程度上不允許進行任何類型的自定義。它們中的大多數(shù)確實未進行記載,但我將在這一部分中向您說明如何使用它們。請不要被 MSDN 幫助中的以下聲明嚇?。骸癧TheTopSecretClassName] 類型支持Microsoft? .NET 框架基礎結(jié)構(gòu),并且不適合直接從您的代碼中使用”。我將在不進行胡亂刪改以及不采用任何反射代碼的前提下使用它們。

一種比相當平常的 "StringBuilder.Append" 代碼生成好得多的方法是利用 System.CodeDom 命名空間中的類,而這正是內(nèi)置代碼生成類(從現(xiàn)在開始簡稱為 codegen)所做的。通過 CodeDom 中包含的一些類,我們可以用一種與語言無關(guān)的方式,在所謂的 AST(抽象語法樹)中表示幾乎所有的編程構(gòu)造。稍后,另一個類(代碼生成器)可以對其進行解釋并生成您期望的原始代碼,例如Microsoft? Visual C# 或Microsoft? Visual Basic?.NET 代碼。這就是 .NET 框架中大多數(shù)代碼生成過程的工作方式。

Codegen 方法不僅利用這一點,還通過映射過程來分離架構(gòu)分析和實際的 CodeDom 生成。對于我們希望為其生成代碼的每個架構(gòu)元素,都必須執(zhí)行該映射。從根本上說,它將構(gòu)建一個新的對象以表示分析的結(jié)果,例如它的結(jié)構(gòu)(這將是要為其生成的類型名)、它的成員以及這些成員的 CLR 類型等。

為了使用這些類,我們將遵循一個基本的工作流程,如下所述:

加載架構(gòu)(原則上加載一個)。

為每個頂級 XSD 元素派生一系列映射。

將這些映射導出到 System.CodeDom.CodeDomNamespace。

在此過程中涉及到四個類,它們都定義在 System.Xml.Serialization 命名空間中:

 

圖 1. 用于獲得 CodeDom 樹的類

可以按以下方式,使用這些類來獲得 CodeDom 樹:

  1. namespace XsdGenerator   
  2. {   
  3.   public sealed class Processor   
  4.   {   
  5.     public static CodeNamespace Process( string xsdFile,    
  6.        string targetNamespace )   
  7.     {   
  8.       // Load the XmlSchema and its collection.   
  9.       XmlSchema xsd;   
  10.       using ( FileStream fs = new FileStream( xsdFile, FileMode.Open ) )   
  11.       {   
  12.         xsd = XmlSchema.Read( fs, null );   
  13.         xsd.Compile( null );   
  14.       }   
  15.       XmlSchemas schemas = new XmlSchemas();   
  16.       schemas.Add( xsd );   
  17.       // Create the importer for these schemas.   
  18.       XmlSchemaImporter importer = new XmlSchemaImporter( schemas );   
  19.       // System.CodeDom namespace for the XmlCodeExporter to put classes in.   
  20.       CodeNamespace ns = new CodeNamespace( targetNamespace );   
  21.       XmlCodeExporter exporter = new XmlCodeExporter( ns );   
  22.       // Iterate schema top-level elements and export code for each.   
  23.       foreach ( XmlSchemaElement element in xsd.Elements.Values )   
  24.       {   
  25.         // Import the mapping first.   
  26.         XmlTypeMapping mapping = importer.ImportTypeMapping(    
  27.           element.QualifiedName );   
  28.         // Export the code finally.   
  29.         exporter.ExportTypeMapping( mapping );   
  30.       }   
  31.       return ns;   
  32.     }   
  33.   }   
  34. }   

這些代碼非常簡單,盡管您可能希望在其中添加異常管理代碼。需要注意的一件事情是 XmlSchemaImporter 通過使用類型的限定名來導入類型,然后將其放在相應的 XmlSchema 中。因此,必須將架構(gòu)中的所有全局元素傳遞給它,然后使用 XmlSchema.Elements 集合進行迭代。該集合像 XmlSchemaElement.QualifiedName 一樣,也是在架構(gòu)編譯之后被填充的所謂的 Post Schema Compilation Infoset(即 PSCI,請參閱 MSDN 幫助)的成員。它具有在解析引用、架構(gòu)類型、繼承、包含等之后填充和組織架構(gòu)信息的作用。其功能類似于 DOM Post Validation Infoset(即 PSVI,請參閱 Dare Obasanjo 的 MSDN 文章和 XSD 規(guī)范)。

您可能已經(jīng)注意到 XmlSchemaImporter 工作方式的一個副作用(實際上是一個缺陷):您只能檢索(導入)全局定義的元素的映射。在架構(gòu)中的任何位置局部定義的任何其他元素將無法通過該機制訪問。這具有我將在后面討論的一些后果,它們可能會限制您可以應用的自定義,或者影響我們的架構(gòu)設計。

XmlCodeExporter 類根據(jù)所導入的映射,用類型定義來填充傳遞給其構(gòu)造函數(shù)的 CodeDomNamespace,從而生成所謂的 CodeDom 樹。通過上述方法得到的 CodeDom 就是 xsd.exe 工具在內(nèi)部生成的東西。有了該樹以后,就可以直接將其編譯為程序集,或者生成源代碼。

如果我希望擺脫 xsd.exe 工具,可以輕松地生成使用該類的控制臺應用程序。為達到該目的,我需要根據(jù)收到的 CodeDom 樹生成一個源代碼文件。我通過創(chuàng)建一個適用于用戶所選的目標語言的 CodeDomProvider 來做到這一點:

  1. static void Main( string[] args )  
  2. {  
  3.   if ( args.Length != 4 )  
  4.   {  
  5.     Console.WriteLine(  
  6.       "Usage: XsdGenerator xsdfile namespace outputfile [cs|vb]" );  
  7.     return;  
  8.   }  
  9.   // Get the namespace for the schema.  
  10.   CodeNamespace ns = Processor.Process( args[0], args[1] );  
  11.   // Create the appropriate generator for the language.  
  12.   CodeDomProvider provider;  
  13.   if ( args[3] == "cs" )  
  14.     provider = new Microsoft.CSharp.CSharpCodeProvider();  
  15.   else if ( args[3] == "vb" )  
  16.     provider = new Microsoft.VisualBasic.VBCodeProvider();  
  17.   else 
  18.     throw new ArgumentException( "Invalid language", args[3] );  
  19.   // Write the code to the output file.  
  20.   using ( StreamWriter sw = new StreamWriter( args[2], false ) )  
  21.   {  
  22.     provider.CreateGenerator().GenerateCodeFromNamespace(  
  23.       ns, sw, new CodeGeneratorOptions() );  
  24.   }  
  25.   Console.WriteLine( "Finished" );  
  26.   Console.Read();  
  27. }  

我可以使用生成器所收到的 CodeGeneratorOptions 實例的屬性,進一步自定義生成的代碼格式和其他選項。

在編譯該控制臺應用程序后,我可以生成與 xsd.exe 工具所生成的完全相同的代碼。有了這一功能,使我完全不必再依賴該工具,并且我不再需要知道該工具是否已安裝或者位于何處,也不再需要為它啟動新的進程,等等。然而,每當我修改架構(gòu)以后,都需要一遍遍地從命令行運行它,這是很不理想的。Microsoft?Visual Studio?.NET 使開發(fā)人員可以通過所謂的自定義工具來利用設計時代碼生成。其中一個例子是類型化數(shù)據(jù)集,當您使用它時(盡管不必具體指定),都會有一個自定義工具在您每次保存數(shù)據(jù)集 XSD 文件時對其進行處理,并自動生成相應的“代碼隱藏”類。

有關(guān)構(gòu)建自定義工具的內(nèi)容超出了本文的范圍,但您可以閱讀更多有關(guān)將我迄今為止所編寫的代碼轉(zhuǎn)換為 該網(wǎng)絡日記張貼中的自定義工具的內(nèi)容。該工具的代碼包含在本文的下載內(nèi)容中,您可以通過將“XsdCodeGen”自定義工具名稱指定給 XSD 文件屬性來簡單地使用它。注冊方法在隨附的自述文件中進行了說明。

即使我能夠找到更容易使用的自定義工具,但是將 xsd.exe 工具替換為另一個執(zhí)行完全相同任務的工具并沒有太大意義,不是嗎?畢竟,我們完成這些工作的原因就是為了改變這種做法!因此,讓我們從這一底線開始對其進行自定義。

【編輯推薦】

  1. ASP.NET 2.0頁面狀態(tài)持續(xù):ViewState與控件
  2. ASP.NET 2.0數(shù)據(jù)綁定控件的自定義集合
  3. 列表控件示例:HeadlineList
  4. ASP.NET 2.0數(shù)據(jù)綁定機制:生成控件
  5. ASP.NET 2.0數(shù)據(jù)綁定的發(fā)展簡述
責任編輯:yangsai 來源: MSDN
相關(guān)推薦

2009-11-13 14:52:24

ADO.NET XML

2009-08-05 18:49:11

XmlSerializ

2009-09-02 18:28:55

.NET框架ESBasic

2009-08-21 16:55:10

.NET框架與XML

2010-01-12 16:20:44

VB.NET類

2009-05-21 13:25:50

.NETCountDownLa微軟

2009-08-05 16:32:25

Smooks 1.2框

2011-05-18 15:40:32

XML

2009-10-28 10:15:48

VB.NET框架類庫

2009-08-04 17:42:23

DataSourceCASP.NET

2009-12-18 16:39:59

ADO.NET基礎類

2023-06-26 07:26:50

System.Net網(wǎng)絡通信基礎接口

2009-07-28 14:40:15

XML數(shù)據(jù)ASP.NET

2024-06-18 13:17:02

數(shù)據(jù)庫框架

2009-09-14 16:46:15

LINQ to XML

2010-09-15 09:18:21

ASP.NET MVC

2011-04-26 14:21:50

MySQL

2011-04-26 15:26:38

PostgreSQL

2009-08-10 09:19:47

.NET反應性框架

2009-07-27 14:46:16

XML和ASP.NET
點贊
收藏

51CTO技術(shù)棧公眾號