利用VC++與MSXML解析XML文檔

來源:互聯網
上載者:User
一、文件物件模型(DOM)
  DOM是Document Object Model(文件物件模型)的簡稱,是對XML文檔進行應用開發、編程的應用程式介面(API)。作為W3C公布的一種跨平台、與語言無關的介面規範,DOM提供了在不同環境和應用中的標準程式介面,可以用任何語言實現。
  DOM採用物件模型和一系列的介面來描述XML文檔的內容和結構,即利用對象把文檔模型化。這種物件模型實現的準系統包括:
  ● 描述文檔表示和操作的介面;
  ● 介面的屬性和方法;
  ● 介面之間的關係以及互操作。
  DOM可對結構化的XML文檔進行解析,文檔中的指令、元素、實體、屬性等所有內容個體都用物件模型表示,整個文檔被看成是一個有結構的資訊樹,而不是簡單的文字資料流,產生的物件模型就是樹的節點,對象同時包含了方法和屬性。因此,對文檔的所有操作都是在對象樹上的進行。在DOM中,樹中的一切都是對象,不管是根節點還是實體的屬性。
  在DOM中主要有以下三個對象:
  ● XML文檔對象
XML文檔既是一種對象,同時又代表整個XML文檔。它由根項目和子項目組成。
  ● XML節點對象
XML節點對象代表的是XML文檔內部的節點,如元素、注釋、名字空間等。
  ● XML節點列表
XML文檔模組列表代表了節點的集合。
  利用DOM,開發人員可以動態地建立XML文檔,遍曆結構,添加、修改、刪除內容等。其物件導向的特性,使人們在處理XML解析相關的事務時節省大量的精力,是一種符合代碼重用思想的強有力編程工具。  二、DOM的四個基本介面(引用自:http://bbs.xml.org.cn/dispbbs.asp?boardID=11&ID=9220)

在DOM介面規範中,有四個基本的介面:Document,Node,NodeList以及NamedNodeMap。在這四個基本介面中,Document介面是對文檔進行操作的入口,它是從Node介面繼承過來的。Node介面是其他大多數介面的父類,象Documet,Element,Attribute,Text,Comment等介面都是從Node介面繼承過來的。NodeList介面是一個節點的集合,它包含了某個節點中的所有子節點。NamedNodeMap介面也是一個節點的集合,通過該介面,可以建立節點名和節點之間的一一映射關係,從而利用節點名可以直接存取特定的節點。下面將對這四個介面分別做一些簡單的介紹。
1、Document介面
Document介面代表了整個XML/HTML文檔,因此,它是整棵文檔樹的根,提供了對文檔中的資料進行訪問和操作的入口。
由於元素、文本節點、注釋、處理指示等都不能脫離文檔的上下文關係而獨立存在,所以在Document介面提供了建立其他節點對象的方法,通過該方法建立的節點對象都有一個ownerDocument屬性,用來表明當前節點是由誰所建立的以及節點同Document之間的聯絡。
在DOM樹中,Document節點是DOM樹中的根節點,也即對XML文檔進行操作的入口節點。通過Docuemt節點,可以訪問到文檔中的其他節點,如處理指示、注釋、文件類型以及XML文檔的根項目節點等等。另外,在一棵DOM樹中,Document節點可以包含多個處理指示、多個注釋作為其子節點,而文件類型節點和XML文檔根項目節點都是唯一的。

關於Document介面的IDL(Interface Definition Language介面定義語言)定義和其中一些比較常用的屬性和方法的詳細介紹可以在MSDN中找到。
2、Node介面
Node介面在整個DOM樹中具有舉足輕重的地位,DOM介面中有很大一部分介面是從Node介面繼承過來的,例如,Element、Attr、CDATASection等介面,都是從Node繼承過來的。在DOM樹中,Node介面代表了樹中的一個節點。
3、NodeList介面
NodeList介面提供了對節點集合的抽象定義,它並不包含如何?這個節點集的定義。NodeList用於表示有循序關聯性的一組節點,比如某個節點的子節點序列。另外,它還出現在一些方法的傳回值中,例如GetNodeByName。
在DOM中,NodeList的對象是"live"的,換句話說,對文檔的改變,會直接反映到相關的NodeList對象中。例如,如果通過DOM獲得一個NodeList對象,該對象中包含了某個Element節點的所有子節點的集合,那麼,當再通過DOM對Element節點進行操作(添加、刪除、改動節點中的子節點)時,這些改變將會自動地反映到NodeList對象中,而不需DOM應用程式再做其他額外的操作。
NodeList中的每個item都可以通過一個索引來訪問,該索引值從0開始。
4、NamedNodeMap介面
實現了NamedNodeMap介面的對象中包含了可以通過名字來訪問的一組節點的集合。不過注意,NamedNodeMap並不是從NodeList繼承過來的,它所包含的節點集中的節點是無序的。儘管這些節點也可以通過索引來進行訪問,但這隻是提供了枚舉NamedNodeMap中所包含節點的一種簡單方法,並不表明在DOM規範中為NamedNodeMap中的節點規定了一種排列順序。
NamedNodeMap表示的是一組節點和其唯一名字的一一對應關係,這個介面主要用在屬性節點的表示上。
與NodeList相同,在DOM中,NamedNodeMap對象也是"live"的。

  

三、MSXML  
    從理論上說,根據XML的格式定義,我們可以自己編寫一個XML的文法分析器,但實際上微軟已經給我們提供了一個XML文法解析器,即一個叫做MSXML.DLL的動態連結程式庫,實際上它是一個COM(Component Object Model)物件程式庫,裡面封裝了進行XML解析時所需要的所有對象。因為COM是一種以二進位格式出現的和語言無關的可重用對象,所以你可以用任何語言(比如VB,VC,DELPHI,C++ Builder甚至是指令碼語言等等)對它進行調用,在你的應用中實現對XML文檔的解析。
  MSXML.DLL所包括的主要COM介面有:
  1. IXMLDOMDocument(Document介面)
DOMDocument對象是XML DOM的基礎,你可以利用它所暴露的屬性和方法來瀏覽、查詢和修改XML文檔的內容和結構。DOMDocument表示了樹的頂層節點,它實現了DOM文檔的所有的基本方法,並且提供了額外的成員函數來支援XSL和XSLT。它建立了一個文檔對象,所有其他的對象都可以從這個文檔對象中得到和建立。
  2. IXMLDOMNode(Node介面)
  IXMLDOMNode是文件物件模型(DOM)中的基本對象,元素、屬性、注釋、過程指令和其他的文檔組件都可以認為是IXMLDOMNode。事實上,DOMDocument對象本身也是一個IXMLDOMNode對象。
  3. IXMLDOMNodeList
  IXMLDOMNodeList實際上是一個節點(Node)對象的集合,節點的增加、刪除和變化都可以在集合中立刻反映出來,可以通過"for.迴圈 "結構來遍曆所有的節點。
  4. IXMLDOMParseError
  IXMLDOMParseError介面用來返回在解析過程中所出現的詳細的資訊,包括錯誤號碼、行號、字元位置和文本描述。
  在具體應用時可以用DOMDocument的Load方法來裝載XML文檔,用IXMLDOMNode 的selectNodes(查詢的結果有多個,得到存放搜尋結果的鏈表)或selectSingleNode(查詢的結果有一個,在有多個的情況下返回找到的第一個節點)方法進行查詢,用createNode和a方法來建立節點和追加節點,用IXMLDOMElement的setAttribute和getAttribute方法來設定和獲得節點的屬性。

此主題相關圖片如下:

四、編程舉例

1、目的文件:  

<book id="bk101">
      <author>lizlex</author>
      <title>XML Developer's Guide</title>
   </book>

2、步驟:

(1)在StdAfx.h中引入動態連結程式庫 MSXML.DLL(C:\windows\system32\msxml4.dll)
 #import <msxml4.dll>

(2)介面設計:
分別放入三個Text,用於輸入資料,與顯示文檔內容用,並添加關聯的成員變數m_strId,m_strAuthor, m_strTitle;並添加確定按鈕:

(3)產生文檔的程式片斷
void CXmlparseDlg::OnButtonGenerate()
{
 UpdateData();

 MSXML2::IXMLDOMDocumentPtr pDoc;
 MSXML2::IXMLDOMElementPtr  xmlRoot ;

    //建立DOMDocument對象
 HRESULT hr = pDoc.CreateInstance(__uuidof(MSXML2::DOMDocument40));
 if(!SUCCEEDED(hr))
 {  
  MessageBox("無法建立DOMDocument對象,請檢查是否安裝了MS XML Parser 運行庫!");
  return ;
 }
 
 //根節點的名稱為Book
 //建立元素並添加到文檔中
 xmlRoot=pDoc->createElement_x_x_x((_bstr_t)"Book");
 
 //設定屬性
 xmlRoot->setAttribute("id",(const char *)m_strId);
 pDoc->a(xmlRoot);
 MSXML2::IXMLDOMElementPtr pNode;

 //添加“author”元素
 pNode=pDoc->createElement_x_x_x((_bstr_t)"Author");
 pNode->Puttext((_bstr_t)(const char *)m_strAuthor);
 xmlRoot->a(pNode);
 
 //添加“Title”元素
 pNode=pDoc->createElement_x_x_x("Title");
 pNode->Puttext((const char *)m_strTitle);
 xmlRoot->a(pNode);
 
 //儲存到檔案
 //如果不存在就建立,存在就覆蓋
 pDoc->save("d:\\he.xml");

}

(4)讀取XML文檔的程式片斷
void CXmlparseDlg::OnButtonLoad()
{
 MSXML2::IXMLDOMDocumentPtr pDoc;
 HRESULT hr;
 hr=pDoc.CreateInstance(__uuidof(MSXML2::DOMDocument40));
 if(FAILED(hr))
 {  
  MessageBox("無法建立DOMDocument對象,請檢查是否安裝了MS XML Parser 運行庫!");
  return ;
 }
 
 //負載檔案
 pDoc->load("d:\\he.xml");
 
 MSXML2::IXMLDOMNodePtr  pNode;
 
 //在樹中尋找名為Book的節點,"//"表示在任意一層尋找
 pNode=pDoc->selectSingleNode("//Book");

 MSXML2::DOMNodeType nodeType;
 
 //得到節點類型
    pNode->get_nodeType(&nodeType);
 
 //節點名稱
 CString strName;
 
 strName=(char *)pNode->GetnodeName();
 
 //節點屬性,放在鏈表中
 MSXML2::IXMLDOMNamedNodeMapPtr pAttrMap=NULL;
 MSXML2::IXMLDOMNodePtr   pAttrItem;
 _variant_t variantValue;
 pNode->get_attributes(&pAttrMap);
 
 long count;
 count=pAttrMap->get_length(&count);
 
 pAttrMap->get_item(0,&pAttrItem);
 //取得節點的值
 pAttrItem->get_nodeTypedValue(&variantValue);
 m_strId=(char *)(_bstr_t)variantValue;
 
 UpdateData(FALSE);
 
}

此主題相關圖片如下:

聯繫我們

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

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

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.