運用Visual Basic 9.0停止XML編程。本站提示廣大學習愛好者:(運用Visual Basic 9.0停止XML編程)文章只能為提供參考,不一定能成為您想要的結果。以下是運用Visual Basic 9.0停止XML編程正文
到目前為止,您能夠已聽說過LINQ(言語集成查詢),它是Visual Studio® 2008中附帶的新查詢技術。啟用LINQ的言語(如Visual Basic®)為您提供了一組豐厚的查詢運算符,您可以將這些運算符使用到各種數據源,如內存中的集合、數據庫、數據集和XML。僅這一項技術就曾經十分優秀了,但Visual Basic 9.0實踐上提供的技術遠不止此,它使XML成為直接集成到言語中的一流數據類型。
如今您能夠想知道為什麼需求將 XML 數據類型直接集成到Visual Basic中。當今,許多使用順序都在運用XML停止存儲和數據傳輸。XML由於其靈敏性和簡易性而在業內普遍采用,而且它還用於許多執行存儲和數據傳輸功用的使用順序。由於 XML具有自描繪性(即數據的構造包括在數據中),因而它特別合適在零碎之間傳輸數據。而且,與為各種自定義文件格式編寫剖析規則相比,閱讀在XML標志外部結構的數據要容易得多。
但XML的問題是,開發人員歷來沒有十分方便地運用過它。令人隱晦和不分歧的API(如文檔對象模型 (DOM))及言語(如XSLT和XQuery)招致編寫的許多單調代碼通常難以閱讀和了解。但在引入LINQ和Visual Basic 9.0之後,XML的開發變得容易多了。在本專欄中,將討論以後的XML 編程體驗,LINQ 如何改良體驗,以及在運用XML時 Visual Basic如何提供更多支持。
運用DOM
首先,假定需求在XML中寫出一個客戶列表。我的客戶列表具有下列屬性:FirstName、LastName、Address、City、State和ZipCode。在將列表轉換為XML時,看上去應如圖1 所示。
Figure1XML中的客戶列表屬性
<Customers>
<Customer FirstName="Jane" LastName="Dow">
<Address>123 Main St</Address>
<City>Redmond</City>
<State>WA</State>
<ZipCode>10104</ZipCode>
</Customer>
<Customer FirstName="Matt" LastName="Berg">
<Address>456 First St</Address>
<City>Seattle</City>
<State>WA</State>
<ZipCode>10028</ZipCode>
</Customer>
</Customers>
運用DOM和Visual Studio 2005,可以編寫代碼遍歷我的列表並結構適當的XML節點,如圖2 所示。您可以看出,關於原本相當復雜的內容也需求編寫許多代碼。而且,由於生成的XML 構造實踐上與代碼的構造不婚配,因而很難直觀顯示其構造。
Figure2運用DOM結構XML節點
'With Visual Basic 9, you no longer have to write code like this.
Public Function ConvertToXML(ByVal custList As List(Of Customer)) _
As String
Dim doc As New XmlDocument
Dim root As XmlElement = doc.CreateElement("Customers")
For Each cust As Customer In custList
Dim custElement As XmlElement = doc.CreateElement("Customer")
custElement.SetAttribute("FirstName", cust.FirstName)
custElement.SetAttribute("LastName", cust.LastName)
Dim address As XmlElement = MakeElement(doc, "Address", cust.Address)
Dim city As XmlElement = MakeElement(doc, "City", cust.City)
Dim state As XmlElement = MakeElement(doc, "State", cust.State)
Dim zipcode As XmlElement = MakeElement(doc, "ZipCode", cust.Zip)
With custElement
.AppendChild(address)
.AppendChild(city)
.AppendChild(state)
.AppendChild(zipcode)
End With
root.AppendChild(custElement)
Next
doc.AppendChild(root)
Return doc.InnerXml
End Function
Private Function MakeElement(ByVal doc As XmlDocument, _
ByVal elementName As String, _
ByVal value As String) As XmlElement
Dim element As XmlElement = doc.CreateElement(elementName)
element.InnerText = value
Return element
End Function
從久遠角度看,維護此代碼將會帶來很大的方便。假如業務需求發作變化並且發現需求添加一些屬性或特性,則必需費力地反省此代碼並確定哪些節點需求更新。
LINQ to XML API
在針對DOM 編碼時,我根本上嘗試從內到外構建XML 樹。這能夠必需湊合API這一關才干完成我的任務。不用在DOM中結構一大堆節點然後將其銜接在一同,假如可以表示 XML的構造然後交換內嵌的值,則操作就會容易得多。這正是經過LINQ to XML API 可以執行的義務,即可以自上而下創立XML(也稱為功用結構)。
運用LINQ,如今我可以編寫圖2中的更冗長更明晰的函數版本。圖3中顯示了新的更為復雜的處理方案。它可以發生與第一個處理方案完全相反的輸入,但可以看出,新的代碼段更冗長且更易於閱讀。我運用XElement和XAttribute對象的結構函數結構了該樹。請留意以下優秀的功用:這些結構函數具有用來傳入其他LINQ to XML對象的重載;例如,我可以將一個XElement 傳入另一個XElement。
Figure3運用LINQ的新處理方案
Public Function ConvertToXML(ByVal custList As List(Of Customer)) As _
String
Dim doc = New XElement("Customers", _
From cust In custList _
Select New XElement("Customer", _
New XAttribute("FirstName", cust.FirstName), _
New XAttribute("LastName", cust.LastName), _
New XElement("Address", cust.Address), _
New XElement("City", cust.City), _
New XElement("State", cust.State), _
New XElement("ZipCode", cust.Zip)))
Return doc.ToString
End Function
第一行創立一個新的XElement,並將其命名為Customers;該行還創立相關的<Customer>和</Customer>標志。傳入結構函數的第二個參數是一個LINQ 查詢,該查詢將成為這些Customer標志中的內容。此查詢遍歷列表中的一切客戶,並將後果轉換為XML。計算 Select語句之後的一切內容,並在運轉時生成 Customer 元素的集合。
由於正在查詢數據,因而可以應用LINQ執行挑選、排序、分組、聯接和其他各種操作。例如,可以經過向查詢中添加 Where子句來修正該函數,使之僅前往寓居在西雅圖的客戶。假如運用DOM執行此操作,則需求在For 循環中添加 If語句。在LINQ中對後果停止排序如今好像在查詢中添加 Order By子句那樣復雜。運用DOM,需求在結構XML 之前手動對後果停止排序。
這裡運用的示例相當復雜,只是想粗淺地說明運用LINQ 可以執行哪些操作。到目前為止,曾經運用了XElement和XAttribute類型。API 定義了許多其他類型,其中包括 XDocument、XNamespace和XComment。
XML文本和嵌入表達式
雖然LINQ to XML提供了比以前更為復雜的體驗,但還可以進一步簡化此辦法。這時便用到了XML文本,它是Visual Basic 9.0中引入的一個新概念。
若要了解 XML文本,必需先了解什麼是文本。請思索以下變量:
Dim someString = "A string literal"
Dim someNumber = 256
Dim someDate = #2/27/2008#
Dim someBoolean = True
此處顯示的每個變量都直接分配了一個值,關於每種狀況,實踐值稱為一個文本。(留意,運用Visual Basic 9.0中新的類型推斷功用,即便沒無為每個變量提供“As <Type>”子句,這些聲明仍為強類型。)
引號中的任何內容都代表一個字符串文本。例如,分配給 someDate的值將是一個日期文本。XML文本與此概念完全相反。可以像在任何其他地位表示數據(以其文本表示方式)一樣精確地表示 XML。即兩邊沒有引號;XML文本不是字符串。可以直接將數據分配給 Customers 變量,如圖4 所示,編譯器會將該值視為文本 XML。因而,變量的類型將被推斷為XElement。
Figure4直接將數據分配給 Customers 變量
Dim customers = <Customers>
<Customer FirstName="Jane" LastName="Dow">
<Address>123 Main St</Address>
<City>Redmond</City>
<State>WA</State>
<Zip>10104</Zip>
</Customer>
<Customer FirstName="Matt" LastName="Berg">
<Address>456 First St</Address>
<City>Seattle</City>
<State>WA</State>
<Zip>10028</Zip>
</Customer>
</Customers>
當編譯器看到此XML時,它會將其轉換為一系列的LINQ to XML API調用。這不但更便於閱讀,而且編譯器會真正優化此結構,並且生成代碼的速度比直接運用API要快。
到目前為止,我完成的一切操作就是將一些XML粘貼到項目中,並將其存儲在變量中(但這不一定有什麼用)。有關在Visual Basic 9.0中運用XML支持的一個罕見曲解是用它將 XML文檔存儲在代碼中。但現實上遠不是這麼回事。關鍵是提供一個復雜的語法來創立、查詢和轉換XML文檔。我演示了如何運用XML文本方便地創立文檔。但是為了運用這種辦法,需求一種方法將值直接拔出XML。這正是嵌入表達式發揚作用的中央。
嵌入表達式本質上通知編譯器“暫停處置此XML文本,計算表達式的值,並將後果插回 XML”。為了完成這一點,我運用了<%= (expression) %>語法。圖5 采用了ConvertToXml 函數,並演示了如何運用XML文本和嵌入表達式對它停止改良。
Figure5運用XML文本和嵌入表達式
Public Function ConvertToXML(ByVal custList As List(Of Customer)) _
As String
Dim doc = <Customers>
<%= From cust In custList _
Select <Customer FirstName=<%= cust.FirstName %>
LastName=<%= cust.LastName %>>
<Address><%= cust.Address %></Address>
<City><%= cust.City %></City>
<State><%= cust.State %></State>
<ZipCode><%= cust.Zip %></ZipCode>
</Customer> %>
</Customers>
Return doc.ToString
End Function
此示例運用LINQ 查詢生成 XML,但要查詢的數據源實踐上是List(Of T)類型的一個內存中的集合。這裡您可以真正理解到LINQ的魅力:我可以對數據庫和其他XML文檔方便地運用與集合相反的查詢運算符,而不用學習每個新的API。並且可以理解到如何從 SQL Server® 數據庫中獲取數據,而且只需求幾行代碼即可方便地將其轉換為XML。
XML屬性
使用順序通常需求反省 XML(能夠經過文件或RSS 源提供),並依據相應數據做出決議。這常常經過XSL 轉換完成,但運用LINQ to XML 則可以省去這種轉換。
在圖6顯示的示例中,我載入了XML文檔,並按寓居在西雅圖的客戶挑選,然後選擇名字和姓氏。在此之後,遍歷查詢並在屏幕上顯示一切婚配的後果。
Figure6運用XML軸屬性的復雜查詢
Public Sub DisplaySeattleCustomers()
Dim filePath = My.Application.Info.DirectoryPath & "customers.xml"
Dim doc = XDocument.Load(filePath)
Dim query = From cust In doc...<Customer> _
Where cust.<City>.Value = "Seattle" _
Select Name = cust.@FirstName & " " & cust.@LastName
For Each name In query
MsgBox(name)
Next
End Sub
乍一看,您能夠以為這裡仿佛出了什麼錯。假如編譯器推斷doc為XDocument類型(並且推斷cust為XElement類型),那麼如何鍵入相似 cust.<City>和cust.@FirstName這樣的內容?XElement顯然不具有這些屬性,這是由於它們特定於加載的XML。這裡實踐發作的狀況是,Visual Basic 編譯器經過一種名為XML屬性的功用節省了少量的任務。
XML屬性有時也稱為XML軸屬性,它提供了一種用於檢索在XML中存儲的值的簡便辦法。在圖6顯示的查詢中,我實踐上運用了全部三個可用軸:子代、元素和屬性。
在XML中,子代是在以後元素下的一個或多個級別中嵌套的元素。表達式“doc...<Customer>”運用子代軸,它的根本含義是“查找名為Customer的一切子代”。記住,我通篇運用的XML 有一個名為Customers的根節點,而且它還包括 Customer 元素。三節點語法本質上轉換為doc.Descendants("Customer")。
上面我將引見 cust.<City>.Value 表達式。在本例中,我運用了元素軸,因而該行轉換為cust.Elements("City").Value。在此處停止比擬之前,您能夠想知道為什麼需求顯式調用.Value(關於屬性不需求此調用)。這是由於像 City這樣的元素可以包括其他元素,因而表達式 cust.<City> 實踐上前往 IEnumerable(Of XElement)。.Value 擴展屬性用於銜接該元素中存儲的一切值,在本例中只是一個復雜的文本值。
最後一個表達式 cust.@FirstName 運用屬性軸。這將轉換為cust.Attributes("FirstName"),並前往屬性中存儲的值。由於屬性不能包括元素,因而不需求調用.Value。然後運用Select 辦法,並將兩個字段兼並為一個名為Name的字段,以便更復雜地停止顯示。
XML架構 IntelliSense
在對最後一個示例停止編碼時,假如IntelliSense®能通知我XML文檔中字段的稱號就太好了。但問題是,編譯器如何知道XML文檔的構造?答案是經過XSD架構。假如有一個XML架構,則可以在Visual Basic中運用Imports語句將該架構引入作用域。在執行此操作後,就會取得基於您的架構的真正 IntelliSense。
運用Visual Basic 2008的XML to Schema工具(可以在go.microsoft.com/fwlink/?LinkId=102501 上下載),您可以依據現有的XML文件疾速創立XSD架構。只需求在XML文件或Web URL中指向該架構,它就會執行生成 XSD文件的單調任務。
完畢語
Visual Basic 是專門為進步任務效率而設計的。隨著企業使用順序在存儲、數據轉換甚至用戶界面方面越來越依賴於 XML,Visual Basic 兼並了一些便於開發人員可以更好地運用XML的功用,這一點很重要。Visual Basic 9.0 在這方面獲得了較大的提高,提供了豐厚的XML支持和弱小的新查詢功用。
運用LINQ提供的復雜而弱小的查詢語法,您可以針對XML 編寫查詢,這與針對數據庫或內存中的集合編寫查詢一樣方便。而且,在開端體驗 Visual Basic 9.0時,你會發現許多本文沒有引見到的XML 新功用,包括對XML 命名空間、正文和片段的內置支持。