国产一级a片免费看高清,亚洲熟女中文字幕在线视频,黄三级高清在线播放,免费黄色视频在线看

打開(kāi)APP
userphoto
未登錄

開(kāi)通VIP,暢享免費(fèi)電子書(shū)等14項(xiàng)超值服

開(kāi)通VIP
使用 MSXML 分析器處理 XML 文檔
 

使用 MSXML 分析器處理 XML 文檔

發(fā)布日期: 8/6/2004 | 更新日期: 8/6/2004

Kenn Scribner

Kenn Scribner 近期有關(guān) XML MSXML DOM 分析器的文章中,僅介紹了該分析器的部分功能。這些文章將 XML 作為一種技術(shù)進(jìn)行了說(shuō)明,但是并沒(méi)有介紹 XML 分析器本身?,F(xiàn)在,Kenn 將回過(guò)頭來(lái)介紹 MSXML 分析器,并講解處理 XML 文檔和節(jié)點(diǎn)所需的基本知識(shí):搜索特定的節(jié)點(diǎn)、插入節(jié)點(diǎn)和檢索節(jié)點(diǎn)值。

MSXML 分析器基于 XML 文檔對(duì)象模型,對(duì)于查看表 1 中所示的各種文檔對(duì)象來(lái)說(shuō),它非常重要。這些對(duì)象直接出自 XML 規(guī)范本身。MSXML 還可以進(jìn)一步將 XML DOM 對(duì)象合并到 COM 中。因此,弄清楚哪個(gè) XML DOM 對(duì)象對(duì)應(yīng)于哪個(gè) MSXML COM 接口非常容易。例如,IXMLDOMNode 代表稱為 Node 的 DOM 對(duì)象。

表 1. XML DOM 對(duì)象及其用途
DOM 對(duì)象用途

DOMImplementation

一個(gè)查詢對(duì)象,用于確定 DOM 支持的級(jí)別

DocumentFragment

表示樹(shù)的一部分(可進(jìn)行剪切/粘貼操作)

Document

表示樹(shù)中的頂級(jí)節(jié)點(diǎn)

NodeList

用于訪問(wèn) XML 節(jié)點(diǎn)的 Iterator 對(duì)象

Node

用于擴(kuò)展帶核心 XML 標(biāo)記的元素

NamedNodeMap

命名空間支持和迭代通過(guò)屬性節(jié)點(diǎn)集合

CharacterData

文本操作對(duì)象

Attr

表示元素的屬性

Element

表示 XML 元素的節(jié)點(diǎn)(可用于訪問(wèn)屬性)

Text

表示給定元素或?qū)傩詫?duì)象的文本內(nèi)容

CDATASection

用于屏蔽 XML 部分,使其不受分析和驗(yàn)證

Notation

包含基于 DTD 或架構(gòu)內(nèi)的表示法

Entity

表示已分析或未分析的實(shí)體

EntityReference

表示實(shí)體引用節(jié)點(diǎn)

ProcessingInstruction

表示處理指令

雖然有時(shí)比較容易混淆,但是 XML 文檔對(duì)象可以是(并且通常是)多態(tài)的。即,“節(jié)點(diǎn)”同時(shí)也是一個(gè)“元素”。當(dāng)您試圖確定需要何種 DOM 對(duì)象來(lái)執(zhí)行何種操作時(shí),這有時(shí)會(huì)造成混淆??梢允褂?#8220;文檔”對(duì)象來(lái)創(chuàng)建 DOM“節(jié)點(diǎn)”,但是,如果要向新創(chuàng)建的節(jié)點(diǎn)添加屬性,就必須通過(guò)其作為“元素”的一面來(lái)訪問(wèn)它。如果說(shuō)存在一種將對(duì)象和操作關(guān)聯(lián)在一起的神奇模式,那么我還沒(méi)能從自己的日常工作中將它提煉出來(lái)。我發(fā)現(xiàn)自己仍需要不斷參考 MSDN 文檔來(lái)查看哪個(gè) COM 接口提供了所需的方法以執(zhí)行我試圖完成的任務(wù)。各種對(duì)象方法看上去的確是按邏輯分組的,這也正是我對(duì) DOM 當(dāng)初的開(kāi)發(fā)模式的推斷(通過(guò)分組邏輯操作)。

因此,其中的訣竅就在于從 MSXML 分析器檢索適當(dāng)?shù)?DOM 對(duì)象,這一操作的具體實(shí)現(xiàn)就是 COM 對(duì)象。操作的基本模式將是:首先實(shí)例化 MSXML COM 對(duì)象本身的一個(gè)副本,然后從該副本請(qǐng)求或以其他方式獲取指向附加 XML DOM 對(duì)象(本身也是 COM 對(duì)象)的指針。

MSXML DOM 試驗(yàn)應(yīng)用程序

創(chuàng)建一個(gè)漂亮的應(yīng)用程序,演示眾多的 MSXML 功能,這很簡(jiǎn)單,但實(shí)際上,附加的代碼只會(huì)畫(huà)蛇添足。相反,我選擇了開(kāi)發(fā)一個(gè)簡(jiǎn)單的基于控制臺(tái)的應(yīng)用程序,該應(yīng)用程序執(zhí)行四種基本操作:

從磁盤(pán)加載一個(gè) XML 文件。

搜索特定的節(jié)點(diǎn),并向該節(jié)點(diǎn)插入一個(gè)子節(jié)點(diǎn)。

搜索另一個(gè)節(jié)點(diǎn),并顯示該節(jié)點(diǎn)內(nèi)包含的(文本)值。

將修改后的 XML 文檔保存回磁盤(pán)中。

為了進(jìn)一步簡(jiǎn)化,我硬編碼了 XML 文檔文件的名稱和 XML 節(jié)點(diǎn)本身。當(dāng)然,如果這是一個(gè)真實(shí)的應(yīng)用程序,您可能很少(或者永遠(yuǎn)不會(huì))采用這樣的方法。但是在本例中,進(jìn)行這些權(quán)衡,是為了簡(jiǎn)化圍繞在 MSXML 功能兩邊的代碼。

像平常一樣,在示例應(yīng)用程序中,我選擇了使用 ATL 來(lái)包裝許多與 COM 有關(guān)的活動(dòng)。您肯定看到我使用了 CComPtr 和 CComQIPtr 對(duì)象,但是我還額外加入了幾個(gè) CComBSTR 和 CComVariant 對(duì)象。如果您不熟悉它們,只需要記住它們是用于處理一些細(xì)節(jié)的模板,這些細(xì)節(jié)對(duì)于本文的主旨來(lái)說(shuō)并非至關(guān)重要,但是從更廣的角度講,還是比較重要的。真正重要的是看到如何搜索 XML 節(jié)點(diǎn),添加新的(具有屬性的)節(jié)點(diǎn),以及顯示節(jié)點(diǎn)內(nèi)包含的文本。

我的基于控制臺(tái)的應(yīng)用程序可以在附帶的 下載文件中找到,它將加載一個(gè)名為 xmldata.xml 的 XML 文檔文件(假定其與可執(zhí)行文件位于同一個(gè)目錄中),并假定該文檔包含以下 XML 數(shù)據(jù):

<?xml version="1.0"?><xmldata>   <xmlnode />   <xmltext>Hello, World!</xmltext></xmldata>

我們將首先搜索 xmlnode 節(jié)點(diǎn),如果找到了該節(jié)點(diǎn),我們將插入一個(gè)新的(帶有屬性的)節(jié)點(diǎn)作為其子級(jí)。生成的 XML 文檔將為:

<?xml version="1.0"?><xmldata>   <xmlnode>      <xmlchildnode xml="fun" />   </xmlnode>   <xmltext>Hello, World!</xmltext></xmldata>

打印 節(jié)點(diǎn)內(nèi)包含的信息 ("Hello, World!") 之后,我們將把該新 XML 文檔保存到名為 updatedxml.xml 的文件中。然后,就可以使用文本編輯器或 Internet Explorer 5.x 來(lái)查看結(jié)果?,F(xiàn)在讓我們轉(zhuǎn)到代碼。

應(yīng)用程序首先初始化了 COM 運(yùn)行庫(kù),然后創(chuàng)建了 MSXML 分析器的一個(gè)實(shí)例:

CComPtr<IXMLDOMDocument> spXMLDOM;HRESULT hr = spXMLDOM.CoCreateInstance(                __uuidof(DOMDocument));if ( FAILED(hr) )     throw "Unable to create XML parser object";if ( spXMLDOM.p == NULL )     throw "Unable to create XML parser object";

如果創(chuàng)建分析器實(shí)例成功,接下來(lái),我們將把 XML 文檔加載到分析器中:

VARIANT_BOOL bSuccess = false;hr = spXMLDOM->load(CComVariant(L"xmldata.xml"),                    &bSuccess);if ( FAILED(hr) )    throw "Unable to load XML document into the parser";if ( !bSuccess )    throw "Unable to load XML document into the parser";

搜索節(jié)點(diǎn)與文檔對(duì)象有關(guān),因此,我們將使用 IXMLDOMDocument::selectSingleNode() 來(lái)根據(jù)其名稱查找特定的 XML 節(jié)點(diǎn)。其他的技巧很多,但是如果準(zhǔn)確地知道要查找的節(jié)點(diǎn)的名稱,這是最直接的方法:

CComBSTR bstrSS(L"xmldata/xmlnode");CComPtr<IXMLDOMNode> spXMLNode;hr = spXMLDOM->selectSingleNode(bstrSS,&spXMLNode);if ( FAILED(hr) )    throw "Unable to locate ‘xmlnode‘ XML node";if ( spXMLNode.p == NULL )    throw "Unable to locate ‘xmlnode‘ XML node";

一些您應(yīng)當(dāng)了解的其他方法包括 IXMLDOMDocument::nodeFromID() 和 IXMLDOMElement::getElementsByTagName(),使用它們可以獲得文檔中的節(jié)點(diǎn)的列表。您還可以將文檔作為樹(shù)來(lái)進(jìn)行訪問(wèn),并依次通過(guò)它(獲取子節(jié)點(diǎn),獲取同輩節(jié)點(diǎn)等)。

任一種情況下,搜索的結(jié)果都是一個(gè) MSXML 節(jié)點(diǎn)對(duì)象 IXMLDOMNode。文檔中必須存在該節(jié)點(diǎn),否則搜索將失敗。我的應(yīng)用程序使用該節(jié)點(diǎn)作為一個(gè)全新 XML 節(jié)點(diǎn)的父級(jí),該新節(jié)點(diǎn)是由 XML 文檔對(duì)象創(chuàng)建的:

CComPtr<IXMLDOMNode> spXMLChildNode;hr = spXMLDOM->createNode(CComVariant(NODE_ELEMENT),                          CComBSTR("xmlchildnode"),                          NULL,                          &spXMLChildNode);if ( FAILED(hr) )    throw "Unable to create ‘xmlchildnode‘ XML node";if ( spXMLChildNode.p == NULL )    throw "Unable to create ‘xmlchildnode‘ XML node";

如果分析器可以創(chuàng)建該節(jié)點(diǎn),下一步就是將它放到 XML 樹(shù)中。IXMLDOMNode::appendChild() 正是完成這一任務(wù)的方法:

CComPtr<IXMLDOMNode> spInsertedNode;hr = spXMLNode->appendChild(spXMLChildNode,                            &spInsertedNode);if ( FAILED(hr) )    throw "Unable to move ‘xmlchildnode‘ XML node";if ( spInsertedNode.p == NULL )    throw "Unable to move ‘xmlchildnode‘ XML node";

如果父節(jié)點(diǎn)的確將新創(chuàng)建的節(jié)點(diǎn)插入為其子級(jí),將返回另一個(gè) IXMLDOMNode 實(shí)例,該實(shí)例表示新的子節(jié)點(diǎn)。實(shí)際上,該新子節(jié)點(diǎn)和傳遞給 appendChild() 的節(jié)點(diǎn)是同一個(gè) XML 節(jié)點(diǎn)。由于在存在問(wèn)題時(shí)附加的子節(jié)點(diǎn)的指針將為 Null,因此,檢查該指針很有用。

到目前為止,我找到了一個(gè)特定的節(jié)點(diǎn),并為它創(chuàng)建了一個(gè)新的子節(jié)點(diǎn),下面,讓我們看看如何處理屬性。假定您要將該屬性添加到新的子節(jié)點(diǎn):

xml="fun"

這并不難,但是您必須從 IXMLDOMNode 切換到 IXMLDOMElement,以便訪問(wèn)該子節(jié)點(diǎn)的元素特征。在實(shí)踐中,這意味著您必須查詢 IXMLDOMNode 接口的相關(guān) IXMLDOMElement 接口,查明后,再調(diào)用 IXMLDOMElement::setAttribute():

CComQIPtr<IXMLDOMElement> spXMLChildElement;spXMLChildElement = spInsertedNode;if ( spXMLChildElement.p == NULL )    throw "Unable to query for ‘xmlchildnode‘ XML _element interface";hr = spXMLChildElement->setAttribute(CComBSTR(L"xml"),                                CComVariant(L"fun"));if ( FAILED(hr) )    throw "Unable to insert new attribute";

此時(shí),已經(jīng)修改了 XML 樹(shù),并創(chuàng)建了所需的樹(shù)。應(yīng)用程序可以在這個(gè)時(shí)候?qū)⑽臋n保存到磁盤(pán),或者執(zhí)行其他任務(wù)?,F(xiàn)在,讓我們來(lái)搜索另一個(gè)節(jié)點(diǎn)并顯示該節(jié)點(diǎn)所包含的值(文本)。您已經(jīng)了解了如何搜索節(jié)點(diǎn),因此,我們將直接講解數(shù)據(jù)提取。

提取節(jié)點(diǎn)數(shù)據(jù)的關(guān)鍵在于使用 IXMLDOMNode::get_nodeTypedValue()??梢允褂?Microsoft 數(shù)據(jù)類(lèi)型架構(gòu)來(lái)標(biāo)識(shí)節(jié)點(diǎn)所包含的數(shù)據(jù),因此可以方便地存儲(chǔ)浮點(diǎn)值、整數(shù)、字符串或該架構(gòu)所支持的任何數(shù)據(jù)類(lèi)型??梢允褂?dt:type 屬性來(lái)指定數(shù)據(jù)類(lèi)型,如下所示:

<model dt:type="string">SL-2</model><year dt:type="int">1992</year>

如果特定的節(jié)點(diǎn)具有指定的數(shù)據(jù)類(lèi)型,就可以使用 get_nodeTypedValue() 以該格式提取數(shù)據(jù)。如果未指定數(shù)據(jù)類(lèi)型,將假定數(shù)據(jù)為文本,分析器將返回具有 BSTR 數(shù)據(jù)的 VARIANT。在本例中,這沒(méi)有任何問(wèn)題,因?yàn)槲覀円阉鞯墓?jié)點(diǎn)是一個(gè)實(shí)際上包含一個(gè)字符串的文本節(jié)點(diǎn)。在需要時(shí),始終可以使用 atoi() 等方法將字符串轉(zhuǎn)換為其他形式。本例中,我們只是提取該字符串?dāng)?shù)據(jù)并顯示它:

CComVariant varValue(VT_EMPTY);hr = spXMLNode->get_nodeTypedValue(&varValue);if ( FAILED(hr) )    throw "Unable to retrieve ‘xmltext‘ text";if ( varValue.vt == VT_BSTR ) {   // Display the results...since we‘re not using the   // wide version of the STL, we need to convert the   // BSTR to ANSI text for display...   USES_CONVERSION;   LPTSTR lpstrMsg = W2T(varValue.bstrVal);   std::cout << lpstrMsg << std::endl;} else {   // Some error   throw "Unable to retrieve ‘xmltext‘ text";} 

如果能夠檢索與節(jié)點(diǎn)關(guān)聯(lián)的值,并且該值為 BSTR(預(yù)期的數(shù)據(jù)類(lèi)型),我們將在屏幕上顯示該文本。如果不能,將顯示一條錯(cuò)誤消息,不過(guò),根據(jù)情況而定,可以方便地采取其他操作。

最后一項(xiàng)與 XML 有關(guān)的操作是將已更新的 XML 樹(shù)保存到磁盤(pán),這一任務(wù)是使用 IXMLDOMDocument::save() 完成的:

hr = spXMLDOM->save(CComVariant("updatedxml.xml"));if ( FAILED(hr) )    throw "Unable to save updated XML document";

完成保存后,向屏幕寫(xiě)一條簡(jiǎn)短說(shuō)明,并退出。

這個(gè)示例應(yīng)用程序無(wú)論如何都算不上漂亮。您可以讓自己的應(yīng)用程序執(zhí)行很多其他功能,但我希望您通過(guò)這個(gè)簡(jiǎn)短的示例了解到了如何從 C++ 程序使用 MSXML 分析器。該分析器本身是一個(gè)復(fù)雜的軟件,無(wú)論怎樣強(qiáng)調(diào)使用 MSDN Library 作為參考,都不能算是過(guò)份。該分析器公開(kāi)了許多接口,這些接口通常會(huì)公開(kāi)許多方法。即便如此,我在自己的項(xiàng)目中仍頻繁地使用該分析器,在親自編寫(xiě)了一些代碼并進(jìn)行試驗(yàn)后,我發(fā)現(xiàn)這個(gè)軟件制作很精良 并且便于使用。我希望您也同樣會(huì)發(fā)現(xiàn)該分析器和一般意義上的 XML 具有廣泛的用途。

要了解有關(guān) Visual C++ Developer 和 Pinnacle Publishing 的更多信息,請(qǐng)?jiān)L問(wèn)他們的 Web 站點(diǎn),網(wǎng)址為: http://www.pinpub.com/

注:這不是 Microsoft Corporation 的網(wǎng)站。Microsoft 對(duì)該網(wǎng)站內(nèi)容不承擔(dān)責(zé)任。

本文復(fù)制自 Visual C++ Developer 的 2000 年 11 月刊。版權(quán)所有 2000,Pinnacle Publishing, Inc.(除非另行說(shuō)明)。保留所有權(quán)利。Visual C++ Developer 是 Pinnacle Publishing, Inc. 獨(dú)立發(fā)行的產(chǎn)品。未經(jīng) Pinnacle Publishing, Inc. 事先同意,不得以任何形式使用或復(fù)制本文的任何部分(評(píng)論文章中的簡(jiǎn)短引用除外)。要聯(lián)系 Pinnacle Publishing, Inc.,請(qǐng)致電 1-800-788-1900。

轉(zhuǎn)到原英文頁(yè)面


本站僅提供存儲(chǔ)服務(wù),所有內(nèi)容均由用戶發(fā)布,如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請(qǐng)點(diǎn)擊舉報(bào)
打開(kāi)APP,閱讀全文并永久保存 查看更多類(lèi)似文章
猜你喜歡
類(lèi)似文章
VC 中利用MSXML解析XML文檔
利用MSXML解析XML文本--浪沙
【轉(zhuǎn)】msxml 操作xml
VB和VB.NET中的XML操作(2)
<VB.net|xml>VB和VB.NET中的XML操作(詳細(xì)介紹)
在.NET Framework中輕松處理XML數(shù)據(jù)(一) - 網(wǎng)易學(xué)院·教程
更多類(lèi)似文章 >>
生活服務(wù)
分享 收藏 導(dǎo)長(zhǎng)圖 關(guān)注 下載文章
綁定賬號(hào)成功
后續(xù)可登錄賬號(hào)暢享VIP特權(quán)!
如果VIP功能使用有故障,
可點(diǎn)擊這里聯(lián)系客服!

聯(lián)系客服