利用VisualBasic操作XML資料

來源:互聯網
上載者:User
visual|xml|資料

什麼是XML

   擴充標記語言XML是一種簡單的資料存放區語言,使用一系列簡單的標記描述資料,而這些標記可以用方便的方式建立,雖然XML佔用的空間比位元據要佔用更多的空間,但XML極其簡單易於掌握和使用。

   XML與Access,Oracle和SQL Server等資料庫不同,資料庫提供了更強有力的資料存放區和分析能力,例如:資料索引、排序、尋找、相關一致性等,XML僅僅是展示資料。事實上XML與其他資料表現形式最大的不同是:他極其簡單。這是一個看上去有點瑣細的優點,但正是這點使XML與眾不同。

   XML的簡單使其易於在任何應用程式中讀寫資料,這使XML很快成為資料交換的唯一公用語言,雖然不同的應用軟體也支援其它的資料交換格式,但不久之後他們都將支援XML,那就意味著程式可以更容易的與Windows、Mac OS, Linux以及其他平台下產生的資訊結合,然後可以很容易載入XML資料到程式中並分析他,並以XML格式輸出結果。

XML的優點

   我們談到XML長於在不同的應用程式之間交換資料,XML檔案也便於構建小的資料庫,不久以前,軟體都使用INI檔案儲存體配置資訊、使用者參數以及其他資訊,後來微軟引入了系統註冊表,接作微軟告訴我們不應該再使用INI檔案了,從那時起Visual Basic對INI檔案的支援被削弱了。但不幸的是註冊表有幾個致命的缺點:不是簡單的文字檔,難於讀寫、可能會變得龐大和緩慢、如果註冊表不知何故出現問題,將有可能造成系統死機。

   將配置資訊放在XML檔案中可以避免這些問題,甚至可以將XML檔案設定為一個共用檔案,這樣在不同的電腦上的使用者就可以共用資料,這是註冊表所不能比擬的。

   在被稱為下一代ASP的ASP.NET中可以在WEB頁中直接使用XML,你可以使用資料繫結控制項直接綁定資料並自動顯示。

   當然也可以不選擇XML,使用文字檔、註冊表、資料庫都可以完成XML所能完成的任務,XML只是你在資料存放區和恢複的另一種工具而已。

XML文法簡介

   XML的文法非常的簡單,XML文檔由節點群組成,使用開啟和關閉節點描述標記,在格式上與HTML標記非常相似,它們之間最大的不同是:XML中可以自由定義標記名。比如下面的標記就描述了一個電話號碼:

<Phone>987-654-3210</Phone> 

   而且不用聲明標記名就可以使用。

   開始和結束標記必須相同,XML是識別大小寫,所以標記的大小寫也必須相同。比如上面的例子中以<Phone>標記開始就必須以</Phone>標記結束,而不能是</phone>或</PHONE>

   節點標記中可以包含屬性,比如下面的代碼中Phone節點包含屬性Type,其值為WorkFax:

<Phone Type="WorkFax">987-654-3210<Phone> 

   如果不願意在節點中包含一個值,那麼可以不需要結束標記,可以用在開始標記的後面加一個斜線來結束節點,在下面的例子中,Phone標記的Number屬性就儲存了一個電話號碼,所以就不需要一個結束標記:

<Phone Type="WorkFax" Number="987-654-3210" /> 

   XML文檔的結構是一個樹形等級結構。文檔必須有一個唯一的根結點,根節點包含所有其它節點。下面我們舉一個較為完整的例子:

<Addresses>
  <Entry Type="Personal">
   <FirstName>Andy</FirstName>
   <LastName>Fickle</LastName>
   <Street>1234 Programmer Place</Street>
   <City>Bugsville</City>
   <State>CO</State>
   <Zip>82379</Zip>
   <Phone Type="Home">354-493-9489</Phone>
  </Entry>
  <Entry Type="Work">
   <FirstName>Betty</FirstName>
   <LastName>Masterson</LastName>
   <Phone Type="Work">937-878-4958</Phone>
   <Phone Type="WorkFax">937-878-4900</Phone>
  </Entry>
  ...
</Addresses> 

   注意相似的節點不需要包含相同的資訊,例如第一個Entry節點包含了地址資訊和家庭電話號碼,第二個Entry節點包含了Work和WorkFax電話號碼,而沒有包含第一個Entry節點包含的資訊。
XML工具

   如前面的例子顯示,XML文法是如此的簡單以至於你可以在很短的時間作一個XML解析器,幸運的是你不必這樣做,因為XML工具可以運行在各種平台上,包括可以安裝了Visual Basic的Windows。

   正是這些L工具而不是XML本身使XML變得更強大和複雜。不同的解析器使你可以某一時刻載入整個XML文檔或只載入某個節點,與此相反,XML Writer 可以同時建立一個XML文檔和節點。

   DOM解析器使我們能夠很方便的載入、複製、排序、修改和儲存XML檔案,遍曆節點獲得名稱或屬性,並給結果排序。雖然他們的功能沒有真正的關聯式資料庫強大,但DOM的這些特點依然非常有用。

   XSD可以定義XML文檔的格式,XSL擴充樣式單定義了怎樣將XML文檔轉換成其他可以在WEB瀏覽器中瀏覽的檔案格式,比如HTML檔案。

   這些工具實際上比XML本身更複雜,所以所有講解XML的書籍都花了很大的篇幅解釋這些XML工具。但這超出了本文的範圍,有興趣的讀者可以參考有關資料。

   Visual Basic.Net提供了使用XML、XSL以及其他XML工具的完整工具。但不用等待VB.NET,微軟XML核心服務(MSXML)版本4.0提供了從Visual Basic6.0載入和儲存XML文檔的工具。

   在msdn.microsoft.com/xml/default.asp中下載最新版本的MSXML,並安裝在電腦上。在Visual Basic 6.0中使用Microsoft XML V4.0象引用其他對象一樣,首先在工程菜單中選擇引用功能表項目,選擇Microsoft V4.0,單擊OK,一切完成後就現在就可以在VB應用程式中添加XML對象了。

DOMDocument 類

   文件物件模型(DOM)使用了一系列相應的對象描述了XML文檔的等級狀態,DOMDocument類是一個描繪XML文檔的DOM結構的MSXML類。

   DOMDocument類僅僅提供了很少的幾個有用的屬性和方法。Load方法載入一個xml檔案,loadxml方法將字串作為xml資料添加到對象中。例如,下面的代碼就將一個小的xml檔案添加到名為xml_document的文檔中。

Dim xml_document As New DOMDocument

xml_document.loadXML _
"<Person>" & vbCrLf & _
" <FirstName>Rod</FirstName>" & vbCrLf & _
" <LastName>Stephens</LastName>" & vbCrLf & _
"</Person>" 

   DOMDocument的xml屬性返迴文檔的xml描述,可以顯示這些傳回值看看這些文檔究竟是什麼樣子,也可以將它儲存為一個檔案,但這完全不必要,因為DOMDocument對象的save方法已經自動將他們儲存了。

   DOMDocument對象的documentElement屬性工作表示文檔資料的根結點,通常情況下操作XML文檔都從這裡開始。

   DOMDocument提供了幾種建立新節點的方法。CreateElement方法為文檔建立一個新的元素節點,其他建立節點的方法有createAttribute, createProcessingInstruction, 和 createTextNode,在這裡就不一一介紹了。

IXMLDOMNode類

   IXMLDOMNode類描述了一個節點,該類提供了一系列用於搜尋和操縱XML文檔的屬性和方法。
selectSingleNode 方法用於搜尋指定節點的後代,用於搜尋指定節點路徑的語言稱為XPATH,XPATH非常棘手,本文就不詳細說明其規範了。下面我們將介紹兩個對搜尋子節點有特別有用並且簡單的方法。

   在給selectsingleNode方法中輸入子節點的名字,該方法將在節點的子節點進行精確匹配搜尋。如果在輸入的字串前面加上".//",那麼將搜尋節點的全部後代。

'' Search for a child node named "LastName."
Set last_name_node = address_node.selectSingleNode("LastName")

'' Search for any descendant named "LastName."
Set last_name_node = address_node.selectSingleNode(".//LastName") 

   下面列出了IXMLDOMNode對象的部分非常有用的屬性:

    attributes.節點屬性集合

    nodeName.節點的標記名

    nodeTypeString.節點的類型

    ownerDocument.返回DOMDocument對象包含的節點

    text.表示節點包含的常值內容。如果該節點包含其他節點,那麼text代表了所有節點的常值內容的組合。

    xml.給出了節點的xml內容,例如:"<FirstName>Rod</FirstName>".

   ChildNodes集合包含了節點的子節點。要給節點增加一個子節點,首先必須給使用DOMDocument對象的節點建立方法,然後將這個建立的節點加入到父節點的childNodes集合中。下面的代碼展示了建立一個新的子節點的子程式,並使用父節點的appendChild方法將其加入到父節點中:

'' Add a new node to the indicated parent node.
Private Sub CreateNode(ByVal indent As Integer, _
ByVal parent As IXMLDOMNode, ByVal node_name As String, _
ByVal node_value As String)
Dim new_node As IXMLDOMNode

'' Create the new node.
Set new_node = parent.ownerDocument.createElement(node_name)

'' Set the node''s text value.
new_node.Text = node_value

'' Add the node to the parent.
parent.appendChild new_node
End Sub 

SaveValues 程式

   現在我們可以使用XML建立一個簡單的程式(如圖1),其值儲存到XML檔案中,在程式開始運行時,程式從VALUE.XML檔案中載入資料,在程式運行結束時,將程式中的現行值存入VALUE.XML檔案中。

 

   下面的代碼是顯示了VALUE.XML檔案的結構:

<Values>
  <FirstName>Rod</FirstName>
  <LastName>Stephens</LastName>
  <Street>1234 Programmer Place</Street>
  <City>Bugsville</City>
  <State>CO</State>
  <Zip>80276</Zip>
</Values> 

   List1顯示了怎樣編寫SaveValues,當載入表單時,form_load事件觸發LoadValues子程式。

   LoadValues建立了一個名為xml_document的DOMDocument對象,然後載入xml檔案,使用selectSingleNode方法尋找名為values的節點,然後使用GetNodeValue方法獲得從value節點後代中得到的值。

   GetNodeValue使用value節點的selectSingleNode方法尋找目標節點,如果節點不存在函數將返回一個預設值,如果找到這個節點GetNodeValue將返回該節點的text值。對於value.xml檔案中的資料節點,text僅僅是包含在節點中的常值內容。

   當表單卸載時觸發form_unload事件,unload事件調用SaveValues子程式。程式建立一個新的DOMDocument對象,該對象建立一個新的名為value的節點,然後用文檔的appendChild方法將節點添加到文檔中。

   在建立所有新的節點後,SaveValues調用DOMDocument''s save方法儲存新的xml檔案。

   注意這個新的檔案已經覆蓋了舊檔案,使用DOMDocument對象無法部分改變XML檔案,可以載入XML檔案,然後修改其中一部分,然後儲存檔案,但原檔案將被完全覆蓋。這是一個小的缺陷,但在這時可以使用其它程式進行修改。

   List1的最後一部分是CreateNode子程式,CreateNode 為父節點建立一個新節點並同時給這個節點賦值。在這個子程式中首先引用一個DOMDocument對象,然後使用該對象的createElement方法建立一個新的節點。

   createNode方法設定節點的text屬性,然後將節點作為子節點添加到父節點中。

   List1:

Option Explicit

Private m_AppPath As String

Private Sub Form_Load()
'' Get the application''s startup path.
m_AppPath = App.Path
If Right$(m_AppPath, 1) <> "\" Then m_AppPath = m_AppPath & "\"

'' Load the values.
LoadValues
End Sub

Private Sub Form_Unload(Cancel As Integer)
'' Save the current values.
SaveValues
End Sub

'' Load saved values from XML.
Private Sub LoadValues()
Dim xml_document As DOMDocument
Dim values_node As IXMLDOMNode

'' Load the document.
Set xml_document = New DOMDocument
xml_document.Load m_AppPath & "Values.xml"

'' If the file doesn''t exist, then
'' xml_document.documentElement is Nothing.
If xml_document.documentElement Is Nothing Then
'' The file doesn''t exist. Do nothing.
Exit Sub
End If

'' Find the Values section.
Set values_node = xml_document.selectSingleNode("Values")

'' Read the saved values.
txtFirstName.Text = GetNodeValue(values_node, "FirstName", "???")
txtLastName.Text = GetNodeValue(values_node, "LastName", "???")
txtStreet.Text = GetNodeValue(values_node, "Street", "???")
txtCity.Text = GetNodeValue(values_node, "City", "???")
txtState.Text = GetNodeValue(values_node, "State", "???")
txtZip.Text = GetNodeValue(values_node, "Zip", "???")
End Sub

'' Return the node''s value.
Private Function GetNodeValue(ByVal start_at_node As IXMLDOMNode, _
ByVal node_name As String, _
Optional ByVal default_value As String = "") As String
Dim value_node As IXMLDOMNode

Set value_node = start_at_node.selectSingleNode(".//" & node_name)
If value_node Is Nothing Then
GetNodeValue = default_value
Else
GetNodeValue = value_node.Text
End If
End Function

'' Save the current values.
Private Sub SaveValues()
Dim xml_document As DOMDocument
Dim values_node As IXMLDOMNode

'' Create the XML document.
Set xml_document = New DOMDocument

'' Create the Values section node.
Set values_node = xml_document.createElement("Values")

'' Add the Values section node to the document.
xml_document.appendChild values_node

'' Create nodes for the values inside the
'' Values section node.
CreateNode values_node, "FirstName", txtFirstName.Text
CreateNode values_node, "LastName", txtLastName.Text
CreateNode values_node, "Street", txtStreet.Text
CreateNode values_node, "City", txtCity.Text
CreateNode values_node, "State", txtState.Text
CreateNode values_node, "Zip", txtZip.Text

'' Save the XML document.
xml_document.save m_AppPath & "Values.xml"
End Sub

'' Add a new node to the indicated parent node.
Private Sub CreateNode(ByVal parent As IXMLDOMNode, _
ByVal node_name As String, ByVal node_value As String)
Dim new_node As IXMLDOMNode

'' Create the new node.
Set new_node = parent.ownerDocument.createElement(node_name)

'' Set the node''s text value.
new_node.Text = node_value

'' Add the node to the parent.
parent.appendChild new_node
End Sub 

SaveValuesIndented 程式

   雖然每個人都化了很大的精力去處理xml文檔,使他們看上更容易些,但xml工具一般都忽略了那些使xml文檔結構明顯的空白和縮排,xml解析器也同樣忽略縮排和空白。

   不幸的是我們例子也同樣忽略了這些縮排和空白,SaveValues建立了一個象下面那樣的xml檔案,所有的代碼都在同一行中。

<Values><FirstName>Rod</FirstName><LastName>Stephens</LastNa
me><Street>1234 Programmer Place</Street><City>Bugsville</Ci
ty><State>CO</State><Zip>80276</Zip></Values> 

   VB.NET中包括了文本寫入類,可以XML文檔規定格式。但MSXML重沒有這種功能,所以如果需要以一種清晰的格式儲存XML檔案,只能另行添加它的格式。

   List2列出了程式SaveValuesIndented使用的代碼,SaveValues子程式與上面例子中講的幾乎完全相同,但他在建立value節點後同時給XML文檔建立了一個<value>標記的新行。

   然後SaveValues 調用CreateNode建立一個新的資料節點,但在這裡它傳遞給CreateNode一個新的參數,這個參數表示這個新節點的縮排方式。

   CreateNode

'' Save the current values.
Private Sub SaveValues()
Dim xml_document As DOMDocument
Dim values_node As IXMLDOMNode

'' Create the XML document.
Set xml_document = New DOMDocument

'' Create the Values section node.
Set values_node = xml_document.createElement("Values")

'' Add a new line.
values_node.appendChild xml_document.createTextNode(vbCrLf)

'' Add the Values section node to the document.
xml_document.appendChild values_node

'' Create nodes for the values inside the
'' Values section node.
CreateNode 4, values_node, "FirstName", txtFirstName.Text
CreateNode 4, values_node, "LastName", txtLastName.Text
CreateNode 4, values_node, "Street", txtStreet.Text
CreateNode 4, values_node, "City", txtCity.Text
CreateNode 4, values_node, "State", txtState.Text
CreateNode 4, values_node, "Zip", txtZip.Text

'' Save the XML document.
xml_document.save m_AppPath & "Values.xml"
End Sub

'' Add a new node to the indicated parent node.
Private Sub CreateNode(ByVal indent As Integer, _
  ByVal parent As IXMLDOMNode, ByVal node_name As String, _
  ByVal node_value As String)
Dim new_node As IXMLDOMNode

'' Indent.
parent.appendChild parent.ownerDocument.createTextNode(Space$(indent))

'' Create the new node.
Set new_node = parent.ownerDocument.createElement(node_name)

'' Set the node''s text value.
new_node.Text = node_value

'' Add the node to the parent.
parent.appendChild new_node

'' Add a new line.
parent.appendChild parent.ownerDocument.createTextNode(vbCrLf)
End Sub 

結論

   本文僅僅揭示XML編程的表面,本文的例子中的涉及只是非常簡單的XML檔案,但你可以使用使用本文揭示的技術做更多的事情,比如配置設定、表單位置、以及其他資訊。XML已經向前更進一步的發展了,有了更複雜的資料層次。對於更複雜的資料結構,在運行時可以更容易的使用MSXML對象來存取XML檔案

 



相關文章

Alibaba Cloud 10 Year Anniversary

With You, We are Shaping a Digital World, 2009-2019

Learn more >

Apsara Conference 2019

The Rise of Data Intelligence, September 25th - 27th, Hangzhou, China

Learn more >

Alibaba Cloud Free Trial

Learn and experience the power of Alibaba Cloud with a free trial worth $300-1200 USD

Learn more >

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。