利用MSXML解析XML文本
當前Web上流行的劇本語(yǔ)言是以HTML為主的語(yǔ)言結構,HTML是一種標記語(yǔ)言,而不是一種編程語(yǔ)言,主要的標記是針對顯示,而不是針對文檔內容本身結構的描述的。也就是說(shuō),機器本身是不能夠解析它的內容的,所以就出現了XML語(yǔ)言。XML (eXtensible Markup Language)語(yǔ)言是SGML語(yǔ)言的子集,它保留了SGML主要的使用功能,同時(shí)大大縮減了SGML的復雜性。XML語(yǔ)言系統建立的目的就是使它不僅能夠表示文檔的內容,而且可以表示文檔的結構,這樣在同時(shí)能夠被人類(lèi)理解的同時(shí),也能夠被機器所理解。XML要求遵循一定的嚴格的標準。XML分析程序比HTML瀏覽器更加要挑剔語(yǔ)法和結構,XML要求正在創(chuàng )建的網(wǎng)頁(yè)正確的使用語(yǔ)法和結構,而不是象HTML一樣,通過(guò)瀏覽器推測文檔中應該是什么東西來(lái)實(shí)現HTML的顯示,XML使得分析程序不論在性能還是穩定性方面都更容易實(shí)現。XML文檔每次的分析結果都是一致的,不象HTML,不同的瀏覽器可能對同一個(gè)HTML作出不同的分析和顯示。同時(shí)因為分析程序不需要花時(shí)間重建不完整的文檔,所以它們能比同類(lèi)HTML能更有效地執行其任務(wù)。它們能全力以赴地根據已經(jīng)包含在文檔中的那個(gè)樹(shù)結構建造出相應的樹(shù)來(lái),而不用在信息流中的混合結構的基礎上進(jìn)行顯示。XML標準是對數據的處理應用,而不是只針對Web網(wǎng)頁(yè)的。任何類(lèi)型的應用都可以在分析程序的上面進(jìn)行建造,瀏覽器只是XML的一個(gè)小的組成部分。當然,瀏覽仍舊極其重要,因為它為XML工作人員提供用于閱讀信息的友好工具。但對更大的項目來(lái)說(shuō)它就不過(guò)是一個(gè)顯示窗口。因為XML具有嚴格的語(yǔ)法結構,所以我們甚至可以用XML來(lái)定義一個(gè)應用層的通訊協(xié)議,比如互聯(lián)網(wǎng)開(kāi)放貿易協(xié)議(Internet Open Trading Protocol)就是用XML來(lái)定義的。從某種意義上說(shuō),以前我們用BNF范式定義的一些協(xié)議和格式從原則上說(shuō)都可以用XML來(lái)定義。實(shí)際上,如果我們有足夠的耐心,我們完全可以用XML來(lái)定義一個(gè)C++語(yǔ)言的規范。
當然,XML允許大量HTML樣式的形式自由的開(kāi)發(fā),但是它對規則的要求更加嚴格。 XML主要有三個(gè)要素:DTD(Document Type Declaration——文檔類(lèi)型聲明)或XML Schema(XML大綱)、XSL(eXtensible Stylesheet Language——可擴展樣式語(yǔ)言)和XLink(eXtensible Link Language——可擴展鏈接語(yǔ)言)。DTD和XML大綱規定了XML文件的邏輯結構,定義了XML文件中的元素、元素的屬性以及元素和元素的屬性之間的關(guān)系;Namespace(名域)實(shí)現統一的XML文檔數據表示以及數據的相互集成;XSL是用于規定XML文檔呈現樣式的語(yǔ)言,它使得數據與其表現形式相互獨立,比如XSL能使Web瀏覽器改變文檔的表示法,例如數據的顯示順序的變化,不需要再與服務(wù)器進(jìn)行通訊。通過(guò)改變樣式表,同一個(gè)文檔可以顯示得更大,或者經(jīng)過(guò)折疊只顯示外面得一層,或者可以變?yōu)榇蛴〉酶袷?。而XLink 將進(jìn)一步擴展目前Web上已有的簡(jiǎn)單鏈接。
XML文檔對象(XML DOM)模型分析
XML DOM 對象提供了一個(gè)標準的方法來(lái)操作存儲在XML文檔中的信息,DOM應用編程接口(API)用來(lái)作為應用程序和XML文檔之間的橋梁。
DOM可以認為是一個(gè)標準的結構體系用來(lái)連接文檔和應用程序(也可以是劇本語(yǔ)言)。MSXML解析器允許你裝載和創(chuàng )建一個(gè)文檔,收集文檔的錯誤信息,得到和操作文檔中的所有的信息和結構,并把文檔保存在一個(gè)XML文件中。DOM提供給用戶(hù)一個(gè)接口來(lái)裝載、到達和操作并序列化XML文檔。DOM提供了對存儲在內存中的XML文檔的一個(gè)完全的表示,提供了可以隨機訪(fǎng)問(wèn)整個(gè)文檔的方法。DOM允許應用程序根據MSXML解析器提供的邏輯結構來(lái)操作XML文檔中的信息。利用MSXML所提供的接口來(lái)操作XML。
實(shí)際上MSXML解析器根據XML文檔生成一個(gè)DOM樹(shù)結構,它能夠讀XML文檔并根據XML文檔內容創(chuàng )建一個(gè)節點(diǎn)的邏輯結構,文檔本身被認為是一個(gè)包含了所有其他節點(diǎn)的節點(diǎn)。
DOM使用戶(hù)能夠把文檔看成是一個(gè)有結構的信息樹(shù),而不是簡(jiǎn)單的文本流。這樣應用程序或者是劇本即使不知道XML的語(yǔ)義細節也能夠方便的操作該結構。DOM包含兩個(gè)關(guān)鍵的抽象:一個(gè)樹(shù)狀的層次、另一個(gè)是用來(lái)表示文檔內容和結構的節點(diǎn)集合。樹(shù)狀層次包括了所有這些節點(diǎn),節點(diǎn)本身也可以包含其他的節點(diǎn)。這樣的好處是對于開(kāi)發(fā)人員來(lái)說(shuō),他可以通過(guò)這個(gè)層次結構來(lái)找到并修改相應的某一個(gè)節點(diǎn)的信息。DOM把節點(diǎn)看成是一個(gè)通常的對象,這樣就有可能創(chuàng )建一個(gè)劇本來(lái)裝載一個(gè)文檔,然后遍歷所有的節點(diǎn),顯示感興趣的節點(diǎn)的信息。注意節點(diǎn)可以有很多中具體的類(lèi)型,比如元素、屬性和文本都可以認為是一個(gè)節點(diǎn)。
微軟的MSXML解析器讀一個(gè)XML文檔,然后把它的內容解析到一個(gè)抽象的信息容器中稱(chēng)為節點(diǎn)(NODES)。這些節點(diǎn)代表文檔的結構和內容,并允許應用程序來(lái)讀和操作文檔中的信息而不需要顯示的知道XML的語(yǔ)義。在一個(gè)文檔被解析以后,它的節點(diǎn)能夠在任何時(shí)候被瀏覽而不需要保持一定的順序。
通過(guò)DOM對XML文檔進(jìn)行解析的圖例如圖1所示。
圖1
對開(kāi)發(fā)人員來(lái)說(shuō),最重要的編程對象是DOMDocument。DOMDocument對象通過(guò)暴露屬性和方法來(lái)允許你瀏覽,查詢(xún)和修改XML文檔的內容和結構,每一個(gè)接下來(lái)的對象暴露自己的屬性和方法,這樣你就能夠收集關(guān)于對象實(shí)例的信息,操作對象的值和結構,并導航到樹(shù)的其他對象上去。
MSXML.DLL所包括的主要的COM接口有:
(1)DOMDocument
DOMDocument對象是XML DOM的基礎,你可以利用它所暴露的屬性和方法來(lái)允許你瀏覽、查詢(xún)和修改XML文檔的內容和結構。DOMDocument表示了樹(shù)的頂層節點(diǎn)。它實(shí)現了DOM文檔的所有的基本的方法并且提供了額外的成員函數來(lái)支持XSL和XSLT。它創(chuàng )建了一個(gè)文檔對象,所有其他的對象都可以從這個(gè)文檔對象中得到和創(chuàng )建。
(2)IXMLDOMNode
IXMLDOMNode是文檔對象模型(DOM)中的基本的對象,元素,屬性,注釋?zhuān)^(guò)程指令和其他的文檔組件都可以認為是IXMLDOMNode,事實(shí)上,DOMDocument對象本身也是一個(gè)IXMLDOMNode對象。
(3)IXMLDOMNodeList
IXMLDOMNodeList實(shí)際上是一個(gè)節點(diǎn)(Node)對象的集合,節點(diǎn)的增加、刪除和變化都可以在集合中立刻反映出來(lái),可以通過(guò)"for...next"結構來(lái)遍歷所有的節點(diǎn)。
(4)IXMLDOMParseError
IXMLDOMParseError接口用來(lái)返回在解析過(guò)程中所出現的詳細的信息,包括錯誤號,行號,字符位置和文本描述。
下面主要描述一個(gè)DOMDocument對象的創(chuàng )建過(guò)程,這里我們用VC描述創(chuàng )建一個(gè)文檔對象的過(guò)程。
HRESULT hr;
IXMLDomDocument* pXMLDoc;
IXMLDOMNode* pXDN;
Hr=CoInitialize(NULL); //COM的初始化
//得到關(guān)于IXMLDOMDocument接口的指針pXMLDOC。
hr=CoCreateInstance(CLSID_DOMDocument,NULL,CLSCTX_INPPROC_SERVER,
IID_IXMLDOMDocument,(void**)&pXMLDoc);
//得到關(guān)于IXMLDOMNode接口的指針pXDN。
hr=pXMLDoc->QueryInterface(IID_IXMLDOMNode,(void**)&pXDN);
在MSXML解析器使用過(guò)程中,我們可以使用文檔中的createElement方法來(lái)創(chuàng )建一個(gè)節點(diǎn)裝載和保存XML文件。通過(guò)load或者是loadXML方法可以從一個(gè)指定的URL來(lái)裝載一個(gè)XML文檔。Load(LoadXML)方法帶有兩個(gè)參數:第一個(gè)參數xmlSource表示需要被解析的文檔,第二個(gè)參數isSuccessful表示文檔裝載是否成功。Save方法是用來(lái)把文檔保存到一個(gè)指定的位置。Save方法有一個(gè)參數destination用來(lái)表示需要保存的對象的類(lèi)型,對象可以是一個(gè)文件,一個(gè)ASP Response方法,一個(gè)XML文檔對象,或者是一個(gè)能夠支持持久保存(persistence)的客戶(hù)對象。下面是save方法使用的一個(gè)簡(jiǎn)單的例子(具體程序請參見(jiàn)http://www.swm.com.cn/swm/200101/利用MSXML解析XML文本)。
同時(shí),在解析過(guò)程中,我們需要得到和設置解析標志。利用不同的解析標志,我們可能以不同的方法來(lái)解析一個(gè)XML文檔。XML標準允許解析器驗證或者不驗證文檔,允許不驗證文檔的解析過(guò)程跳過(guò)對外部資源的提取。另外,你可能設置標志來(lái)表明你是否要從文檔中移去多余的空格。
為了達到這個(gè)目的,DOMDocument對象暴露了下面幾個(gè)屬性,允許用戶(hù)在運行的時(shí)候改變解析器的行為:
(1)Async(相對于C++是兩個(gè)方法,分別為get_async和put_async)
(2)ValidateOnparse (相對于C++是兩個(gè)方法,分別為get_validateOnParse和 put_validateOnParse)
(3)ResolveExternals(相對于C++是兩個(gè)方法,分別為get_ ResolveExternals和put_ ResolveExternals)
(4)PersercveWhiteSpace(相對于C++是兩個(gè)方法,分別為get_ PersercveWhiteSpace和put_ PersercveWhiteSpace)
每一個(gè)屬性可以接受或者返回一個(gè)Boolean值。缺省的,anync,validateOnParse,resolveExternals的值為T(mén)RUE,perserveWhiteSpace的值跟XML文檔的設置有關(guān),如果XML文檔中設置了xml:space屬性的話(huà),該值為FALSE。
同時(shí)在文檔解析過(guò)程中可以收集一些和文檔信息的信息,實(shí)際上在文檔解析過(guò)程中可以得到以下的信息:
(1)doctype(文檔類(lèi)型):實(shí)際上是和用來(lái)定義文檔格式的DTD文件。如果XML文檔沒(méi)有相關(guān)的DTD文檔的話(huà),它就返回NULL。
(2)implementation(實(shí)現):表示該文檔的實(shí)現,實(shí)際上就是用來(lái)指出當前文檔所支持的XML的版本。
(3)parseError(解析錯誤):在解析過(guò)程中最后所發(fā)生的錯誤。
(4)readyState(狀態(tài)信息):表示XML文檔的狀態(tài)信息,readyState對于異步使用微軟的XML解析器來(lái)說(shuō)的重要作用是提高了性能,當異步裝載XML文檔的時(shí)候,你的程序可能需要檢查解析的狀態(tài),MSXML提供了四個(gè)狀態(tài),分別為正在狀態(tài),已經(jīng)狀態(tài),正在解析和解析完成。
(5)url(統一資源定位):關(guān)于正在被裝載和解析的XML文檔的URL的情況。注意如果該文檔是在內存中建立的話(huà),這個(gè)屬性返回NULL值。
在得到文檔樹(shù)結構以后,我們可以操作樹(shù)中的每一個(gè)節點(diǎn),可以通過(guò)兩個(gè)方法得到樹(shù)中的節點(diǎn),分別為nodeFromID和getElementsByTagName。
nodeFromID包括兩個(gè)參數,第一個(gè)參數idString用來(lái)表示ID值,第二個(gè)參數node返回指向和該ID相匹配的NODE節點(diǎn)的接口指針。注意根據XML的技術(shù)規定,每一個(gè)XML文檔中的ID值必須是唯一的而且一個(gè)元素(element)僅且只能和一個(gè)ID相關(guān)聯(lián)。
getElementsByTagName方法有兩個(gè)參數,第一個(gè)參數tagName表示需要查找的元素(Element)的名稱(chēng),如果tagName為"*"的話(huà)返回文檔中所有的元素(Element)。第二個(gè)參數為resultList,它實(shí)際是指向接口IXMLDOMNodeList的指針,用來(lái)返回和tagName(標簽名字)相關(guān)的所有的Node的集合。
下面是一個(gè)簡(jiǎn)單的例子
下面是save方法使用的一個(gè)簡(jiǎn)單的例子:
BOOL DOMDocSaveLocation() { BOOL bResult = FALSE; IXMLDOMDocument *pIXMLDOMDocument = NULL; HRESULT hr; try { _variant_t varString = _T("D:\\sample.xml"); // 這里需要創(chuàng )建一個(gè)DOMDocument對象和裝載XML文檔,代碼省略. hr = pIXMLDOMDocument->save(varString); //保存文檔到D:\\sample.xml中去。 if(SUCCEEDED(hr)) bResult = TRUE; } catch(...) { DisplayErrorToUser(); // 這里需要釋放對IXMLDOMDocument接口的引用,代碼省略。 } return bResult; }
例子2
IXMLDOMDocument *pIXMLDOMDocument = NULL;
wstring strFindText (_T("author"));
IXMLDOMNodeList *pIDOMNodeList = NULL;
IXMLDOMNode *pIDOMNode = NULL;
long value; BSTR bstrItemText;
HRESULT hr;
try { // 創(chuàng )建一個(gè)DOMDocument文檔對象,并裝載具體文檔,相關(guān)代碼省略。
//下面的代碼用來(lái)得到一個(gè)和標簽名稱(chēng)author相關(guān)的所有的節點(diǎn)集合
hr = pIXMLDOMDocument->getElementsByTagName( (TCHAR*)strFindText.data(), &pIDOMNodeList);
SUCCEEDED(hr) ? 0 : throw hr; //是否正確的得到了指向IDOMNodeList的指針。
hr = pIDOMNodeList->get_length(&value); //得到所包含的NODE節點(diǎn)的個(gè)數
if(SUCCEEDED(hr)) { pIDOMNodeList->reset(); for(int ii = 0; ii < value; ii++) { //得到具體的一個(gè)NODE節點(diǎn)
pIDOMNodeList->get_item(ii, &pIDOMNode);
if(pIDOMNode ) { pIDOMNode->get_text(&bstrItemText); //得到該節點(diǎn)相關(guān)的文本信息
::MessageBox(NULL, bstrItemText,strFindText.data(), MB_OK);
pIDOMNode->Release(); pIDOMNode = NULL; }
}
}
pIDOMNodeList->Release(); pIDOMNodeList = NULL;
}
catch(...)
{ if(pIDOMNodeList) pIDOMNodeList->Release();
if(pIDOMNode) pIDOMNode->Release();
DisplayErrorToUser();
}
簡(jiǎn)單的實(shí)例程序
#include //下面的.h文件是在安裝了最新的XML Parser以后所包含的.h文件。
#include "C:\Program Files\Microsoft XML Parser SDK\inc\msxml2.h"
#include void main()
{ // 初始化COM接口
CoInitialize(NULL); //在程序中,我們假定我們裝載的XML文件名稱(chēng)為xmldata.xml,它缺省的和可執行文
//件在同一個(gè)目錄中。該文件的內容如下:
// // // // Hello, World! // //
//程序將尋找名為"xmlnode"的節點(diǎn),然后插入一個(gè)新的名稱(chēng)為"xmlchildnode"的
//節點(diǎn),然后它去尋找一個(gè)名為"xmltest"的節點(diǎn),然后提取包含在節點(diǎn)中的文本并顯
//示它。最后它把新的改變過(guò)的XML文檔保存在名稱(chēng)為"updatexml.xml"的文檔中。
try { // 通過(guò)智能指針創(chuàng )建一個(gè)解析器的實(shí)例。
CComPtr spXMLDOM;
HRESULT hr = spXMLDOM.CoCreateInstance(__uuidof(DOMDocument));
if ( FAILED(hr) ) throw "不能創(chuàng )建XML Parser對象";
if ( spXMLDOM.p == NULL ) throw "不能創(chuàng )建XML Parser對象";
// 如果對象創(chuàng )建成功的話(huà),就開(kāi)始裝載XML文檔 VARIANT_BOOL bSuccess = false;
hr = spXMLDOM->load(CComVariant(L"xmldata.xml"),&bSuccess);
if ( FAILED(hr) ) throw "不能夠在解析器中裝載XML文檔";
if ( !bSuccess ) throw "不能夠在解析器中裝載XML文檔";
// 檢查并搜索"xmldata/xmlnode" CComBSTR bstrSS(L"xmldata/xmlnode");
CComPtr spXMLNode;
//用接口IXMLDOMDocument的方法selectSingleNode方法定位該節點(diǎn)
hr = spXMLDOM->selectSingleNode(bstrSS,&spXMLNode);
if ( FAILED(hr) ) throw "不能在XML節點(diǎn)中定位‘xmlnode‘ ";
if ( spXMLNode.p == NULL ) throw "不能在XML節點(diǎn)中定位‘xmlnode‘ ";
//DOM對象"spXMLNode"現在包含了XML節點(diǎn),所以我們可以在
//它下面創(chuàng )建一個(gè)子節點(diǎn)并把找到的該節點(diǎn)作為它的父節點(diǎn)。
CComPtr spXMLChildNode; //用接口IXMLDOMDocument的方法createNode方法創(chuàng )建一個(gè)新節點(diǎn)。
hr = spXMLDOM->createNode( CComVariant(NODE_ELEMENT), CComBSTR("xmlchildnode"), NULL,&spXMLChildNode);
if ( FAILED(hr) ) throw "不能創(chuàng )建‘xmlchildnode‘ 節點(diǎn)";
if ( spXMLChildNode.p == NULL ) throw "不能創(chuàng )建‘xmlchildnode‘ 節點(diǎn)";
//添加新節點(diǎn)到spXMLNode節點(diǎn)下去。
CComPtr spInsertedNode;
hr = spXMLNode->appendChild(spXMLChildNode,&spInsertedNode);
if ( FAILED(hr) ) throw "不能創(chuàng )建‘xmlchildnode‘ 節點(diǎn)";
if ( spInsertedNode.p == NULL ) throw "不能移動(dòng)‘xmlchildnode‘ 節點(diǎn)"; //對新節點(diǎn)添加屬性。
CComQIPtr spXMLChildElement;
spXMLChildElement = spInsertedNode;
if ( spXMLChildElement.p == NULL ) throw "不能在XML元素接口中查詢(xún)到‘xmlchildnode‘ ";
//設置新節點(diǎn)的屬性
hr = spXMLChildElement->setAttribute(CComBSTR(L"xml"),CComVariant(L"fun"));
if ( FAILED(hr) ) throw "不能插入新的屬性"; //下面的程序段用來(lái)尋找一個(gè)節點(diǎn)并顯示該節點(diǎn)的相關(guān)信息
// 查找"xmldata/xmltext"節點(diǎn)
spXMLNode = NULL; // 釋放先前的節點(diǎn)
bstrSS = L"xmldata/xmltext";
hr = spXMLDOM->selectSingleNode(bstrSS,&spXMLNode);
if ( FAILED(hr) ) throw "不能定位‘xmltext‘節點(diǎn)";
if ( spXMLNode.p == NULL ) throw "不能定位‘xmltext‘節點(diǎn)"; // 得到該節點(diǎn)包含的文本并顯示它
CComVariant varValue(VT_EMPTY);
hr = spXMLNode->get_nodeTypedValue(&varValue);
if ( FAILED(hr) ) throw "不能提取‘xmltext‘文本";
if ( varValue.vt == VT_BSTR )
{ // 顯示結果,注意這里要把字符串從形式BSTR轉化為ANSI USES_CONVERSION;
LPTSTR lpstrMsg = W2T(varValue.bstrVal);
std::cout << lpstrMsg << std::endl; } // if else { // 如果出現錯誤 throw "不能提取‘xmltext‘文本"; }
// else //保存修改過(guò)的XML文檔到指定的文檔名
hr = spXMLDOM->save(CComVariant("updatedxml.xml"));
if ( FAILED(hr) ) throw "不能保存修改過(guò)的XML文檔";
std::cout << "處理完成..." << std::endl << std::endl; }
// try catch(char* lpstrErr) { // 出現錯誤
std::cout << lpstrErr << std::endl << std::endl; }
// catch catch(...) { // 未知錯誤
std::cout << "未知錯誤..." << std::endl << std::endl; }
// catch // 結束對COM的使用
CoUninitialize();
}
最后我們討論一下如何來(lái)創(chuàng )建新的節點(diǎn),實(shí)際上可以通過(guò)方法createNode來(lái)創(chuàng )建一個(gè)新的節點(diǎn)。CreateNode包括四個(gè)參數,第一個(gè)參數Type表示要創(chuàng )建的節點(diǎn)的類(lèi)型,第二個(gè)參數name表示新節點(diǎn)的nodeName的值,第三個(gè)參數namespaceURI表示該節點(diǎn)相關(guān)的名字空間,第四個(gè)參數node表示新創(chuàng )建的節點(diǎn)。注意可以通過(guò)使用已經(jīng)提供的類(lèi)型(Type),名稱(chēng)(name)和名字空間(nodeName)來(lái)創(chuàng )建一個(gè)節點(diǎn)。
當一個(gè)節點(diǎn)被創(chuàng )建的時(shí)候,它實(shí)際上是在一個(gè)名字空間范圍(如果已經(jīng)提供了名字空間的話(huà))內創(chuàng )建的。如果沒(méi)有提供名字空間的話(huà),它實(shí)際上是在文檔的名字空間范圍內創(chuàng )建的。
利用MSXML進(jìn)行XML文檔分析的簡(jiǎn)單實(shí)例為了說(shuō)明如何在VC中使用XML DOM模型,這里我們顯示了一個(gè)簡(jiǎn)單的實(shí)例程序(具體程序請參見(jiàn)http://www.swm.com.cn/swm/200101/利用MSXML解析XML文本),是一個(gè)Console Application。下面是主要的程序代碼,本代碼用來(lái)在一個(gè)XML文檔中定位一個(gè)特殊的Node節點(diǎn),并插入一個(gè)新的子節點(diǎn)。
為了說(shuō)明如何在VC中使用XML DOM模型,這里我們顯示了一個(gè)簡(jiǎn)單的實(shí)例程序(具體程序請參見(jiàn)http://www.swm.com.cn/swm/200101/利用MSXML解析XML文本),是一個(gè)Console Application。下面是主要的程序代碼,本代碼用來(lái)在一個(gè)XML文檔中定位一個(gè)特殊的Node節點(diǎn),并插入一個(gè)新的子節點(diǎn)。總結
XML文檔因為有著(zhù)比HTML嚴格的多的語(yǔ)法要求,所以使用和編寫(xiě)一個(gè)XML解析器要比編寫(xiě)一個(gè)HTML的解析器要容易的多。同時(shí)因為XML文檔不僅可以標記文檔的顯示屬性,更重要的是它標記了文檔的結構和包含信息的特征,所以我們可以方便的通過(guò)XML解析器來(lái)獲取特定節點(diǎn)的信息并加以顯示或修改,方便了用戶(hù)對XML文檔的操作和維護。同時(shí)我們需要注意的是XML是一種開(kāi)放的結構體系并不依賴(lài)于任何一家公司,所以開(kāi)發(fā)基于XML的應用必然會(huì )得到絕大多數軟件開(kāi)發(fā)平臺的支持。另外,我們也可以看到,象微軟這樣的軟件開(kāi)發(fā)主流企業(yè)也把目光定位在基于XML+COM的體系上,無(wú)論是微軟的Office系列、Web服務(wù)器和瀏覽器還是數據庫產(chǎn)品(SQL Server)都已經(jīng)開(kāi)始支持基于XML的應用。通過(guò)XML來(lái)定制應用程序的前端,COM來(lái)實(shí)現具體的業(yè)務(wù)對象和數據庫對象,使系統具有更加靈活的擴展性和維護性。
聯(lián)系客服