使用微軟的XML Parser創(chuàng)建XML文檔
發(fā)表時間:2024-02-16 來源:明輝站整理相關(guān)軟件相關(guān)文章人氣:
[摘要]XML提供了不同或不相似的系統(tǒng)之間表達或交流信息的功能強大和靈活的方式。XML也是基于文本格式的,它在許多方面與HTML相似。例如,XML文檔中也包含有開始(例如<font>)、結(jié)束(例如</font>)標志。與HTML不同的是,我們可以在XML中使用任何喜歡的標志━━使用...
XML提供了不同或不相似的系統(tǒng)之間表達或交流信息的功能強大和靈活的方式。XML也是基于文本格式的,它在許多方面與HTML相似。例如,XML文檔中也包含有開始(例如<font>)、結(jié)束(例如</font>)標志。與HTML不同的是,我們可以在XML中使用任何喜歡的標志━━使用多少標志或如何給它們命名都由我們自己來定。
MXXMLWriter組件基礎(chǔ)知識
創(chuàng)建XML文檔的最大困難在于,XML文檔應該符合一些基本的格式規(guī)則━━例如確保其中的元素不會重迭。盡管我們可以很容易地保證新的XML文檔符合XML規(guī)格所定義的基本格式,但使用第三方的組件來管理它的輸出會更加簡單和安全。在本篇文章中我們將介紹的是MXXMLWriter,它是微軟的MS XML Parser 3.0的一部分。
說起解析器,我們一般會想到在其輸入端需要輸入一些數(shù)據(jù),然后在其輸出端得到一系列的符號。微軟的XML Parser與規(guī)則解析器的作用非常相似,它在輸入端接受一個XML文檔,然后在輸出端生成一個XML文檔對象模型(DOM)━━XML文檔的一種基于對象的表達方式,或者生成一系列的Simple API for XML(SAX)事件。無論生成哪種輸出格式,其輸入都是XML文檔。
MXXMLWriter是微軟XML parser的一部分,對于通過編程方式創(chuàng)建XML文檔非常有用。使用MXXMLWriter比自己動手創(chuàng)建XML文檔有許多好處,其中包括:
·MXXMLWriter產(chǎn)生的XML文檔符合W3C XML 1.0 Namespace推薦標準,我們無需關(guān)心輸出格式,因為解析器能夠為我們解決這一切。
·我們可以將MXXMLWriter的輸出與SAX Content Handler綁定在一塊兒,以較少的內(nèi)存快速進行處理。
·基于界面的編程模式使我們的代碼更容易閱讀和維護,我們可以將輸出發(fā)送給一個支持IStream界面的String或COM對象。
處理XML文檔的基礎(chǔ)知識
在能夠使用MXXMLWriter組件創(chuàng)建新的XML文檔之前,我們需要了解一些處理XML文檔的基本知識,因為MXXMLWriter希望使用它的應用程序能夠成為SAX事件提供者。
處理XML文檔有二種方式:使用文檔對象模型(DOM)或者Simple API for XML(SAX)。二種方法在各種應用中各有優(yōu)、缺點,DOM在XML文檔查詢方面有優(yōu)勢,SAX在快速處理超大型XML文檔方面有優(yōu)勢,而且能夠使我們完全控制解析的過程。
使用DOM處理XML文檔
當將XML文檔加載至DOM中時,XML解析器會讀取整個文檔,在內(nèi)存中創(chuàng)建許多表達這一文檔的對象。下面的圖1顯示了一個簡單的XML文檔片段和DOM如何在內(nèi)存中表示它:
圖1顯示,Document類的實例表示一個XML文檔(圖1中的第一部分),XML文檔中包含有節(jié)點(圖1中的第二部分),這些節(jié)點是DOM Node對象的實例。(圖1中的第三部分)。
一旦DOM已經(jīng)將全部XML文檔讀入內(nèi)存,DOM就為你處理XML文檔作好所有的準備了。我們可以通過使用循環(huán)重復處理其中的內(nèi)容、使用XPath表達式查詢特定的節(jié)點或隨機訪問DOM樹的任意部分對DOM中的元素進行操作。關(guān)健是我們的應用程序能夠?qū)ML文檔進行完整的控制,可以從文檔在內(nèi)存中的表示中提取所需要的信息。
使用SAX處理XML文檔
SAX編程模式與DOM編程模式完全不同。通過讓應用程序截獲XML解析器在處理XML文檔時產(chǎn)生的事件,SAX可以使應用程序更接近XML解析器。由于事件是被推送到應用程序中的,因此,它提供的是一種“推”編程模式,應用程序無需象在使用DOM時那樣作為一個控制點。
,XML Reader(圖2中的第一部分)負責讀取XML文檔。XML Reader請求了我們提供的一個組件,它在讀取XML文檔時調(diào)用了其界面中的方法。(圖2中的第二部分)我們的應用程序(圖2中的第三部分)則使用組件的輸出。
在圖2中,一個包含有ISAXXMLReader的組件被用作XML Reader。要使用SAX處理XML文檔,需要在ISAXContentHandler界面中注冊一個組件。當XML Reader遇到文檔中的元素時,它調(diào)用ISAXContentHandler方法處理startDocument、startElement等元素和提供有關(guān)XML Reader讀取的元素信息的字符。圖3顯示了一個事件的序列,該事件序列是XML Reader在處理樣例文件(圖1、2中出現(xiàn)的)時生成的。
使用MXXMLWriter創(chuàng)建XML文檔
MXXMLWriter是SAX的消費者,意味著使用MXXMLWriter的應用程序是SAX的提供者,MXXMLWriter使用SAX事件編寫出正確格式的XML文檔。
本篇文章中的例子代碼是一個能夠讀取以“,”分割的文件并產(chǎn)生XML文檔的控制臺應用程序,它產(chǎn)生的XML文檔顯示在屏幕上,我們可以將其輸出捕捉到文本文件中,并保存在磁盤上。例子代碼使用STL(標準模板庫)對文件的讀取進行管理。下面的表1顯示了MXXMLWriter的具體代碼,它能夠建立指向ISAXContentHandler等界面的指針:
Listing 1 - Instanciating MXXMLWriter// MSXML2::IMXWriterPtr是一個智能化指針
MSXML2::IMXWriterPtr pXMLWriter;
pXMLWriter.CreateInstance(__uuidof(MSXML2::MXXMLWriter));
// ISAXContentHandler是一個由MXXMLWriter使用的界面
MSXML2::ISAXContentHandlerPtr pContentHandler;
pContentHandler=pXMLWriter; //calls QI for ISAXContentHandler on pXMLWriter
//ISAXErrorHandler是一個由MXXMLWriter使用的界面
MSXML2::ISAXErrorHandlerPtr pErrorHandler;
pErrorHandler=pXMLWriter; //calls QI for ISAXErrorHandler on pXMLWriter
// ISAXDTDHandler也是由MXXMLWriter使用的界面
MSXML2::ISAXDTDHandlerPtr pDTDHandler;
pDTDHandler=pXMLWriter; //calls QI for ISAXDTDHandler on pXMLWriter
//將輸出內(nèi)容輸出到一個字符串中
pXMLWriter->put_output(CComVariant(L""));
一旦MXXMLWriter完成了,程序就會讀取文本文件,并生成供MXXMLWriter處理的SAX事件。程序如下面的表2所示:
表2:生成供MXXMLWriter使用的事件
std::getline(fileIn,lineFromFile);
while(fileIn.good())
{
npos=lineFromFile.find_first_of(",",nlast);
//確定當前行有一個“,”號;
//如果沒有發(fā)現(xiàn),find_first_of返回std::wstring::npos
if(npos!=std::wstring::npos){
wElementName=A2W(lineFromFile.substr(nlast,npos-nlast).c_str());
// startElement元素
pContentHandler->startElement(L"",0,L"",0,
const_cast<wchar_t*>(wElementName.c_str()),
wElementName.length(),NULL);
nlast= ++npos;
// 獲取當前行的其他部分(元素值)
wElementValue=A2W(lineFromFile.substr(nlast).c_str());
// 字符
pContentHandler->characters(
const_cast<wchar_t*>(wElementValue.c_str()),
wElementValue.length());
// endElement元素
pContentHandler->endElement(L"",0,L"",0,
const_cast(wElementName.c_str()),
wElementName.length());
}
std::getline(fileIn,lineFromFile);
nlast=0;
}
上面的程序置于一個由輸入文件的狀態(tài)控制的循環(huán)中,它使用std::getline(...)方法逐行讀取輸入文件,并將讀取的行存儲在std::string類型變量lineFromFile中。MXXMLWriter期望的輸入數(shù)據(jù)類型為Unicode字符串,程序使用ANSI字符串使文檔的解析更簡單。這樣,程序在把從文件中讀取的ANSI字符串在傳遞給MXXMLWriter之前才轉(zhuǎn)換為Unicode字符串。
輸入文件是文本文件,每行中包括一個元素和元素值對兒。程序代碼能夠?qū)τ稍睾驮刂祵M成的XML文檔進行處理。
表3:樣例文本文件
author, Essam Ahmed
topic, Using the Microsoft XML Parser...
author, Essam Ahmed
topic, Using the Microsoft XML Parser...
<?xml version="1.0" encoding="UTF-16" standalone="no"?>
<RootElement>
<author>Essam Ahmed</author>
<topic>Using the Microsoft XML Parser...</topic>
</ RootElement>
程序把其輸出內(nèi)容輸出到屏幕上,如果想把輸出保存在文件中,可以使用重定向符>將輸出內(nèi)容輸出到一個文件中。
結(jié)束語
這篇文章介紹了如何使用Microsoft XML 3.0 Parser中的一個組件━━MXXMLWriter來創(chuàng)建XML文檔。使用MXXMLWriter比自己編寫類似的代碼有幾點好處,它不但符合現(xiàn)有的標準,而且在標準改變時也無需升級自己的代碼。