• <ins id="pjuwb"></ins>
    <blockquote id="pjuwb"><pre id="pjuwb"></pre></blockquote>
    <noscript id="pjuwb"></noscript>
          <sup id="pjuwb"><pre id="pjuwb"></pre></sup>
            <dd id="pjuwb"></dd>
            <abbr id="pjuwb"></abbr>
            隨筆-2  評論-2  文章-0  trackbacks-0
            原文地址:http://msdn.microsoft.com/msdnmag/issues/07/04/Xml/Default.aspx?loc=zh

            ??? 盡管 .NET Framework 不斷取得成功,Microsoft 仍然認真對待本機 C++ 開發(fā)。通過引入 XmlLite(適合于用本機 C++ 編寫的應(yīng)用程序的高性能、低開銷 XML 讀取器和寫入器)說明了這一點。

            托管代碼通過 System.Xml 命名空間廣泛支持 XML,而依賴于 COM 的傳統(tǒng) Visual Basic? 和 C++ 應(yīng)用程序可以訪問 Microsoft? XML 核心服務(wù) (MSXML) 中的類似功能。但是,這些并沒有為需要快速精簡的 XML 分析器的本機 C++ 開發(fā)人員提供富有吸引力的選項。開始使用 XmlLite 吧。

            本文將探討您可以對 XmlLite 執(zhí)行的操作。但是,首先,為設(shè)定預(yù)期,我希望快速回顧一下 XmlLite 未提供的內(nèi)容,至少是此初始版本中未提供的內(nèi)容。對于初學者,它既未提供文檔對象模型 (DOM) 實現(xiàn),也未提供 XML 架構(gòu)或文檔類型定義 (DTD) 驗證。它還缺少對高級工具的支持,例如基于光標的導航(如 XPath)、樣式表和序列化。但是,通過建立在 XmlLite 之上的功能,可以根據(jù)需要填補任何空白,Microsoft .NET Framework 中的幾乎所有 XML 功能同樣都建立在 XmlReader 和 XmlWriter 類之上。

            那么,XmlLite 提供了哪些內(nèi)容?簡單地說,它提供了非緩存的只進分析器(提供接收式編程模型)和非緩存的只進 XML 生成器。已證明這兩者是非常有價值的功能。


            為什么推出新的 XML 分析器?

            開發(fā)人員日益熟悉他們每天使用的庫,通過廣泛使用 XML,他們肯定會詢問有關(guān)新推出的 XML 分析器的一些疑難問題。要了解這一新分析器的價值,讓我們首先考慮一下 XML 分析器當今的情形。

            很自然地,如果應(yīng)用程序已經(jīng)利用 .NET Framework,則決定通常是很簡單的:只需使用 System.Xml 即可。為證明這一點,XmlLite 的設(shè)計基于 .NET Framework 中 XmlReader 和 XmlWriter 類的設(shè)計。從以 C++ 編寫的托管應(yīng)用程序使用 XmlLite 通常沒有優(yōu)勢。XmlLite 的功能畢竟比 XmlReader 和 XmlWriter 類提供的功能要少得多。(圖?1 中的表略述 XmlLite 中的主要類型如何映射到 .NET Framework 中的主要類型。)另一方面,如果應(yīng)用程序僅使用本機代碼,那么就 Microsoft 技術(shù)而言,MSXML 在傳統(tǒng)上是所選的解決方案。

            MSXML 提供了兩個差異很大的 XML 分析器。第一個分析器是在各種情形下可用的 DOM 實現(xiàn)。如果使用較小的 XML 文檔且需要隨機訪問 XML 文檔進行內(nèi)存中讀取和寫入,則 DOM 實現(xiàn)是一種合理的選擇。MSXML 的更高版本引入了“用于 XML 的簡單 API (SAX2)”的實現(xiàn)。它實際上是否簡單是有爭議的。使用 SAX2 時(甚至在開始之前),您需要實現(xiàn)至少兩個 COM 接口:一個用于接收 XML 文檔中各個節(jié)點的通知,另一個用于接收分析錯誤的通知。

            將 SAX2 實現(xiàn)添加到 MSXML 的原因如下:與 DOM 實現(xiàn)不同,SAX2 分析器以數(shù)據(jù)流形式讀取 XML 文檔,并通知您何時到達各個節(jié)點。這意味著,您的應(yīng)用程序的內(nèi)存使用量并不隨所分析文檔的大小而增加。

            SAX2 存在的問題以及 .NET Framework 不提供其實現(xiàn)的原因在于 SAX2 模型的內(nèi)在復雜性。它要求實現(xiàn)接口或事件,并強制開發(fā)人員使用更為間接的編程模型,要求開發(fā)人員管理注定會使應(yīng)用程序變得復雜的其他狀態(tài)。相反,.NET Framework 中的 XmlReader 和 XmlWriter 類以及 XmlLite 的 IXmlReader 和 IXmlWriter 接口提供了簡單易懂的分析器,可以直接在函數(shù)中使用,而不必管理任何外部狀態(tài)或通知。

            由于其設(shè)計的簡明性,XmlLite 能夠提供相當好的性能,即使與 MSXML SAX2 實現(xiàn)相比也是如此。雖然 SAX2 分析器可以比 DOM 實現(xiàn)更好地處理大型文檔,但是與 XmlLite 相比就遜色了。

            簡單地說,XmlLite 優(yōu)于 MSXML,且它更易于從本機 C++ 使用。MSXML 仍將是 Visual Basic 和基于 COM 的腳本語言的最可行解決方案,但是現(xiàn)在本機 Visual C++? 最終具有了專門為它設(shè)計的 XML 分析器。雖然 Windows Vista? 和更高版本中附帶有 XmlLite,但是一個更新對于 Windows? XP 和 Windows Server? 2003 的 32 位和 64 位版本也是可用的。因為未涉及 COM 注冊,所以此更新包應(yīng)該不會導致 MSXML 通常造成的有關(guān)安裝和版本控制的難題。

            Back to top

            COM“Lite”

            XmlLite 不僅是易記的名稱;事實上,它是一個輕型 XML 分析器。XmlLite 利用了 COM 的精華,即編程規(guī)范和約定,并拋棄了復雜的和可能不必要的部分,如 COM 注冊、運行時服務(wù)、代理、線程模型、封送處理等。

            從 XmlLite.dll 導出的函數(shù)創(chuàng)建 XML 讀取器和寫入器。通過鏈接到 XmlLite.lib 并包括 Windows SDK 中的 XmlLite.h 頭文件,可以訪問它們。生成的 COM 樣式接口使用熟悉的 IUnknown 接口方法進行生存期管理。COM IStream 接口也起到一定作用并表示存儲器。除此之外,沒有 COM 的依賴項;無需注冊任何 COM 類或甚至調(diào)用強制性的 CoInitialize 函數(shù)。活動模板庫 (ATL) CComPtr 類處理剩余的一小部分 COM。但是,您確實需要關(guān)注線程安全,因為出于單線程方案中的性能,XmlLite 不是線程安全的。

            我在以下示例中使用 COM_VERIFY 宏,以便清晰地識別方法在何處返回需要檢查的 HRESULT。可以將此替換為相應(yīng)的錯誤處理 - 不管該操作引發(fā)異常還是您自己返回 HRESULT。

            Back to top

            讀取 XML

            XmlLite 提供了返回 IXmlReader 接口實現(xiàn)的 CreateXmlReader 函數(shù):

            CComPtr<IXmlReader> reader;
            COM_VERIFY(::CreateXmlReader(__uuidof(IXmlReader),
                                         reinterpret_cast<void**>(&reader),
                                         0));
            

            雖然是可選的,但是 CComPtr 類模板確保迅速釋放接口指針。

            CreateXmlReader 接受接口標識符 (IID) 以及指向 void 指針的指針。這是 COM 編程中的常見模式,允許調(diào)用方指定要返回的接口指針的類型。我的示例使用 __uuidof 運算符,該運算符是 Microsoft 特定的關(guān)鍵字,用于提取與類型關(guān)聯(lián)的 GUID。在這種情況下,它用于檢索接口的 IID。CreateXmlReader 的最后一個參數(shù)接受可選的 IMalloc 實現(xiàn)以允許調(diào)用方控制內(nèi)存分配。

            創(chuàng)建讀取器后,需要指示讀取器將用作輸入的存儲器。IStream 接口表示存儲器,這樣就可以將 XmlLite 與可能設(shè)計的任何流實現(xiàn)一起使用:

            CComPtr<IStream> stream;
            
            // Create stream object here...
            
            COM_VERIFY(reader->SetInput(stream));
            

            (我將在本文的后面部分中討論流。)

            設(shè)置 XML 讀取器的輸入后,可以通過重復調(diào)用 Read 方法進行讀取。Read 方法接受一個可選參數(shù),該參數(shù)在每次成功調(diào)用時返回節(jié)點類型。Read 方法返回 S_OK 以指示已從流中成功讀取下一個節(jié)點,返回 S_FALSE 以指示已到達流的結(jié)尾處。以下是如何依次枚舉節(jié)點的一個示例:

            HRESULT result = S_OK;
            XmlNodeType nodeType = XmlNodeType_None;
            
            while (S_OK == (result = reader->Read(&nodeType)))
            {
                // Get node-specific info
            }
            

            要枚舉當前節(jié)點的屬性,請使用 MoveToFirstAttribute 和 MoveToNextAttribute 方法。如果已成功地重新定位讀取器,則這兩種方法都返回 S_OK;如果不存在更多的屬性,則返回 S_FALSE。以下示例說明如何依次枚舉給定節(jié)點的屬性:

            for (HRESULT result = reader->MoveToFirstAttribute(); 
                 S_OK == result;
                 result = reader->MoveToNextAttribute())
            {
                // Get attribute-specific info
            }
            

            調(diào)用 IXmlReader 的 Read 方法時,它會將任何節(jié)點屬性自動存儲在內(nèi)部集合中。這樣,您就可以使用 MoveToAttributeByName 方法,按名稱將讀取器移動到特定的屬性。但是,枚舉屬性并將其存儲在應(yīng)用程序特定的數(shù)據(jù)結(jié)構(gòu)中,效率通常更高。請注意,您還可以使用 GetAttributeCount 方法確定當前節(jié)點中的屬性數(shù)。

            確定節(jié)點或?qū)傩院螅@取其信息就很簡單了。以下示例演示如何獲取給定節(jié)點的命名空間 URI 和本地名稱:

            PCWSTR namespaceUri = 0;
            UINT namespaceUriLength = 0;
            
            COM_VERIFY(reader->GetNamespaceUri(&namespaceUri, 
                                               &namespaceUriLength));
            
            PCWSTR localName = 0;
            UINT localNameLength = 0;
            
            COM_VERIFY(reader->GetLocalName(&localName, 
                                            &localNameLength));
            

            返回字符串值的所有 IXmlReader 方法都遵循此模式。第一個參數(shù)接受指向?qū)捵址羔槼A康闹羔槨5诙€參數(shù)是可選的;如果它不為零,則它將返回以字符度量的字符串長度(不包括空結(jié)束符)。

            以下是強調(diào)性能的另一個示例。僅在將讀取器移動到其他節(jié)點或以某種其他方式(如通過設(shè)置新的輸入流或釋放 IXmlReader 接口)使當前節(jié)點無效之前,從 IXmlReader 方法返回的字符串指針才是有效的。換句話說,IXmlReader 不會將流的副本返回給調(diào)用方。

            與其在 .NET Framework 中的對應(yīng)方不同,IXmlReader 未提供讀取鍵入內(nèi)容的任何方法。例如,如果特定的元素或?qū)傩园瑪?shù)字或日期,則您需要首先獲取其字符串表示形式,然后根據(jù)需要自己進行轉(zhuǎn)換。.NET Framework 的 XmlReader 類中存在的許多其他 helper 方法也不存在于 IXmlReader 中,但是可以作為 helper 函數(shù)編寫。XmlLite 確實符合最小接口設(shè)計的 C++ 理論。

            圖?2 顯示使用 IXmlReader 讀取 XML 文檔時涉及的對象和抽象。但是,請牢記,IStream 可以抽取任何存儲,此處顯示的文件僅僅是一個常見示例。

            圖 2 讀取器
            圖 2?讀取器
            Back to top

            寫入 XML

            XmlLite 提供了返回 IXmlWriter 接口實現(xiàn)的 CreateXmlWriter 函數(shù):

            CComPtr<IXmlWriter> writer;
            
            COM_VERIFY(::CreateXmlWriter(__uuidof(IXmlWriter),
                                         reinterpret_cast<void**>(&writer),
                                         0));
            

            創(chuàng)建寫入器后,需要指示寫入器將用作輸出的存儲器:

            CComPtr<IStream> stream;
            
            // Create stream object here
            
            COM_VERIFY(writer->SetOutput(stream));
            

            開始寫入之前,可以修改寫入器屬性。XmlWriterProperty 枚舉定義可用的屬性。例如,您可能希望指定是否縮進 XML 輸出以便于讀者閱讀(使用 SetProperty 方法可以做到這一點):

            COM_VERIFY(writer->SetProperty(XmlWriterProperty_Indent, TRUE));
            

            然后可以開始使用 IXmlWriter 方法寫入基礎(chǔ)流。XmlLite 支持 XML 片段。如果計劃寫入完整的 XML 文檔,則應(yīng)該從調(diào)用 WriteStartDocument 方法(它負責寫入 XML 聲明)開始。聲明取決于所用的編碼,但是默認編碼為 UTF-8,它在大多數(shù)情況下都應(yīng)該是合適的。(稍后將介紹文本編碼。)提供了許多 WriteXxx 方法,用于寫入各種節(jié)點類型、屬性和值。

            請考慮以下示例:

            COM_VERIFY(writer->WriteStartDocument(XmlStandalone_Omit));
            COM_VERIFY(writer->WriteStartElement(0, L"html", 
                                                 L"http://www.w3.org/1999/xhtml"));
            
            COM_VERIFY(writer->WriteStartElement(0, L"head", 0));
            COM_VERIFY(writer->WriteElementString(0, L"title", 0, L"My Web Page"));
            COM_VERIFY(writer->WriteEndElement()); // </head>
            
            COM_VERIFY(writer->WriteStartElement(0, L"body", 0));
            COM_VERIFY(writer->WriteElementString(0, L"p", 0, L"Hello world!"));
            
            COM_VERIFY(writer->WriteEndDocument());
            

            WriteStartDocument 方法處理將 XML 聲明寫入流的操作。它只有一個參數(shù),該參數(shù)接受來自 XmlStandalone 枚舉的值,指示是否出現(xiàn)獨立的文檔聲明,如果是這樣,則指示它保存的值。寫入 XML 片段時,通常省略對 WriteStartDocument 的調(diào)用。

            WriteStartElement 方法接受以下三個參數(shù):第一個參數(shù)指定元素的可選命名空間前綴,第二個參數(shù)指定元素的本地名稱,第三個參數(shù)指定可選的命名空間 URI。WriteElementString 是 XmlLite 提供的非常方便的方法之一。用于寫入 XHTML 文檔標題的以下代碼等效于上一示例中使用的 WriteElementString:

            COM_VERIFY(writer->WriteStartElement(0, L"title", 0));
            COM_VERIFY(writer->WriteString(L"My Web Page"));
            COM_VERIFY(writer->WriteEndElement());
            

            顯然,WriteElementString 方法不是絕對必要的,但它確實很有用。

            最后,WriteEndDocument 方法用于關(guān)閉文檔。您可能已注意到,未顯式關(guān)閉 body 和 html 元素。WriteEndDocument 會自動關(guān)閉任何打開的元素。就此而言,釋放寫入器也會關(guān)閉任何剩余的元素。但是,如果您不小心,則未顯式關(guān)閉此類元素的做法可能會導致錯誤,因為流的生存期和寫入器的生存期通常可以不同。要說的是,如果需要確保已將所有要寫入的內(nèi)容寫入基礎(chǔ)流,則只需調(diào)用 IXmlWriter 的 Flush 方法即可。

            圖?3 顯示使用 IXmlWriter 寫入 XML 文檔時涉及的對象和抽象流。請牢記,IStream 可以抽取任何存儲,此處的文件僅僅是一個常見示例。

            圖 3 寫入器
            圖 3?寫入器
            Back to top

            使用流

            到此為止,我對流進行的介紹并不多。與一些功能更全面的 XML 庫不同,XmlLite 未提供任何支持從公共存儲位置(如文件或通過網(wǎng)絡(luò)協(xié)議)讀取和向其寫入的功能。正因為這一點,對于希望從其讀取或向其寫入的任何存儲器,您都需要提供 IStream 實現(xiàn)。實現(xiàn) IStream 接口并不復雜,但是在許多情況下,您不需要執(zhí)行此操作,因為實現(xiàn)可能已存在。

            CreateStreamOnHGlobal 函數(shù)提供由虛擬內(nèi)存支持的 IStream 實現(xiàn)。第一個參數(shù)是使用 GlobalAlloc 函數(shù)創(chuàng)建的可選內(nèi)存句柄。但是,只需傳遞零,CreateStreamOnHGlobal 即可為您創(chuàng)建內(nèi)存對象。以下示例創(chuàng)建一個由系統(tǒng)內(nèi)存支持且將根據(jù)需要動態(tài)增長的 IStream 實現(xiàn):

            CComPtr<IStream> stream;
            COM_VERIFY(::CreateStreamOnHGlobal(0, TRUE, &stream));
            

            釋放流將釋放內(nèi)存。

            SHCreateStreamOnFile 函數(shù)提供了另一個有用的 IStream 實現(xiàn)。它創(chuàng)建由文件支持的 IStream:

            CComPtr<IStream> stream;
            COM_VERIFY(::SHCreateStreamOnFile(L"D:\\Sample.xml",
                                              STGM_WRITE | STGM_SHARE_DENY_WRITE,
                                              &stream));
            

            Back to top

            讀取時的文本編碼

            雖然默認情況下 XmlLite 使用 UTF-8 進行寫入,但是如果在讀取時嘗試檢測文本編碼,則可以覆蓋此行為。首先,讓我們看一下您將自動獲取的信息。對于給定的流,IXmlReader 將通過作為 XML 前同步碼的字節(jié)順序標記來檢測編碼提示。IXmlReader 還將允許在 XML 聲明中指定的任何編碼。期望任何 XML 分析器都具有這兩個特征。如果具有可能未定義任何編碼信息的輸入流,而且 XmlLite 無法試探性地確定正使用的編碼,則可以將 IXmlReader 定向到特定的編碼(如果給定了代碼頁或編碼名稱)。

            可以假借 IXmlReaderInput 接口創(chuàng)建 XML 讀取器輸入對象,而不是將流直接傳遞到 IXmlReader。提供了兩個用于創(chuàng)建包裝輸入流的輸入對象的函數(shù)。CreateXmlReaderInputWithEncodingCodePage 函數(shù)接受代碼頁編號形式的代碼。CreateXmlReaderInputWithEncodingName 函數(shù)接受使用其規(guī)范名稱的編碼。除此之外,這兩個函數(shù)具有完全相同的簽名。概括一下,通常可以對 XML 讀取器的輸入流進行如下設(shè)置:

            CComPtr<IStream> stream;
            
            // Create stream object here
            
            COM_VERIFY(reader->SetInput(stream));
            

            要覆蓋編碼,請將代碼更改為:

            CComPtr<IStream> stream;
            
            // Create stream object here
            
            CComPtr<IXmlReaderInput> input;
            
            COM_VERIFY(::CreateXmlReaderInputWithEncodingName(stream,
                                                              0, // default allocator
                                                              L"ISO-8859-8",
                                                              TRUE, // hint
                                                              0, // base URI
                                                              &input));
            
            COM_VERIFY(reader->SetInput(input));
            

            第一個參數(shù)指示 XML 讀取器將從其讀取的流。第二個參數(shù)接受可選的 IMalloc 實現(xiàn)。如果提供的話,則它將覆蓋 XML 讀取器自己的實現(xiàn)。第三個參數(shù)指定編碼名稱。msdn2.microsoft.com/ms752827.aspx 上的文檔列出了本機支持的編碼;要支持其他編碼,可以提供 IMultiLanguage2 接口實現(xiàn)。下一個參數(shù)指示是否必須使用指定的編碼或者它是否僅僅是一個提示。如果指定 TRUE,則指示分析器嘗試使用建議的編碼,但是如果它失敗,則可以隨意嘗試試探性地確定實際的編碼。如果指定 FALSE,則指示分析器嘗試建議的編碼;如果它與輸入流不匹配,則返回錯誤。下一個參數(shù)接受可能用于解析外部實體的可選基本 URI。最后一個參數(shù)返回表示要傳遞到 SetInput 方法的輸入對象的接口指針。

            Back to top

            寫入時的文本編碼

            XML 寫入器將基于傳遞到 SetOutput 方法的對象確定要使用的編碼。如果該對象實現(xiàn) IStream 接口或者甚至實現(xiàn)有限的 ISequentialStream 接口,則 XML 寫入器將使用 UTF-8 編碼。可以創(chuàng)建 XML 寫入器輸出對象來覆蓋此行為。提供了兩個用于創(chuàng)建包裝輸出流的輸出對象的函數(shù)。CreateXmlWriterOutputWithEncodingCodePage 函數(shù)接受代碼頁編號形式的編碼,而 CreateXmlWriterOutputWithEncodingName 函數(shù)接受使用其規(guī)范名稱的編碼。除此之外,這兩個函數(shù)具有完全相同的簽名。通常,可以對 XML 寫入器的輸出流進行如下設(shè)置:

            CComPtr<IStream> stream;
            
            // Create stream object here
            
            COM_VERIFY(writer->SetOutput(stream));
            

            要覆蓋默認編碼,請編寫以下代碼:

            CComPtr<IStream> stream;
            
            // Create stream object here
            
            CComPtr<IXmlWriterOutput> output;
            
            COM_VERIFY(::CreateXmlWriterOutputWithEncodingName(stream,
                                                               0,
                                                               L"ISO-8859-8",
                                                               &output));
            
            COM_VERIFY(writer->SetOutput(output));
            

            第一個參數(shù)指示 XML 寫入器將寫入的流。第二個參數(shù)接受可選的 IMalloc 實現(xiàn)。如果提供的話,則它將覆蓋 XML 寫入器自己的實現(xiàn)。第三個參數(shù)指定編碼名稱。最后一個參數(shù)返回表示要傳遞到 SetOutput 方法的輸出對象的接口指針。

            Back to top

            處理大數(shù)據(jù)值

            為了在讀取大數(shù)據(jù)值時限制內(nèi)存使用,XML 讀取器提供了按數(shù)據(jù)塊讀取值的機制。IXmlReader ReadValueChunk 方法讀取的字符數(shù)不超過規(guī)定的最大字符數(shù),在預(yù)料到后續(xù)調(diào)用時向前移動讀取器。以下示例說明如何重復調(diào)用 ReadValueChunk 以讀取大數(shù)據(jù)值:

            CString value;
            
            WCHAR chunk[256] = { 0 };
            HRESULT result = S_OK;
            UINT charsRead = 0;
            
            while (S_OK == (result = reader->ReadValueChunk(chunk,
                                                            countof(chunk),
                                                            &charsRead)))
            {
                value.Append(chunk, charsRead);
            }
            

            當不再有數(shù)據(jù)可用時,ReadValueChunk 返回 S_FALSE。在此示例中,我要將數(shù)據(jù)塊寫入 CString 對象。這僅僅是為了說明如何管理數(shù)據(jù)塊的長度,顯然這在實際中會抵消數(shù)據(jù)分塊的優(yōu)勢。

            Back to top

            安全注意事項

            以 XML 為中心的應(yīng)用程序必須總是處理來自不可信源的 XML。XmlLite 提供了許多工具以保護應(yīng)用程序免受已知漏洞和將來漏洞的攻擊。

            XML 文檔可以包含對外部實體的引用。一些 XML 分析器自動解析這些實體。雖然此方法可能很有用,但是,如果未仔細編寫 XML 解析程序以緩解各種威脅,則此方法可能會造成安全漏洞的攻擊。XmlLite 既不自動解析外部實體,也不提供 XML 解析程序。要提供自己的實現(xiàn)(如有必要),請實現(xiàn) IXmlResolver 接口并將 XmlReaderProperty_XmlResolver 屬性與 IXmlReader SetProperty 方法一起使用,以指示讀取器使用您的解析程序。

            XML 文檔可能還包含 DTD 處理說明。雖然 XmlLite 不支持文檔驗證(使用 XML 架構(gòu)或 DTD),但是它支持 DTD 實體擴展和默認屬性。由于這些 DTD 可以包含對外部實體的引用,因此它們可能會使您的應(yīng)用程序受到各種攻擊。默認情況下,XmlLite 禁用 DTD 處理。通過將 XmlReaderProperty_DtdProcessing 屬性設(shè)置為 DtdProcessing_Parse 值,可以允許 DTD 處理。此外,還存在由 XmlReaderProperty_MaxEntityExpansion 控制的 DTD 實體擴展攻擊(也稱為 billion laughs 攻擊)的內(nèi)置緩解措施。此屬性的默認值為 100,000。

            攻擊者可以利用使用 XML 的應(yīng)用程序的另一種方法是,創(chuàng)建名稱非常長的文檔。如果未能阻止,則這可能用盡巨大的內(nèi)存并允許拒絕服務(wù)攻擊。我已經(jīng)提示了可以執(zhí)行的方法。緩解此類威脅的一種明顯方法是,按數(shù)據(jù)塊讀取大數(shù)據(jù)值,如上一部分所述。另一種有用的方法是,提供限制內(nèi)存分配的自定義 IMalloc 實現(xiàn)。如果輸入流支持隨機訪問,則還可以指示 XML 讀取器使用 XmlReaderProperty_RandomAccess 屬性來避免緩存屬性。這將減少用于讀取開始元素標記的內(nèi)存量,但是也可能降低分析速度,因為分析器必須來回查找以便在請求時檢索各個屬性值。

            如果 XML 層次結(jié)構(gòu)過深,則也可能快速用盡系統(tǒng)資源。要阻止攻擊者提供層次結(jié)構(gòu)過深的 XML 文檔,可以使用 XmlReaderProperty_MaxElementDepth 屬性限制分析器將允許的深度。此屬性默認為 256。

            Back to top

            總結(jié)

            XmlLite 為本機 C++ 應(yīng)用程序提供了功能強大的 XML 分析器。它著重于性能,知道它所使用的系統(tǒng)資源,為控制這些特征提供了很大的靈活性。XmlLite 支持所有的常見文本編碼,是一種非常有用的實用工具,可以簡化本機 C++ 應(yīng)用程序中的 XML 使用。有關(guān)詳細信息,請參閱 msdn2.microsoft.com/ms752872.aspx 上的 XmlLite 文檔。

            posted on 2007-03-31 16:50 Canny 閱讀(1058) 評論(2)  編輯 收藏 引用

            評論:
            # re: 用于本機 C++ 的小巧快捷的 XML 分析器 2007-04-01 08:40 | 空明流轉(zhuǎn)
            COM啊。。。這點我還是比較的喜歡TinyXML。功能差不多也就夠了。。。  回復  更多評論
              
            # re: 用于本機 C++ 的小巧快捷的 XML 分析器 2007-04-16 13:40 | 復合管個
            直接拷貝別人的文章有意思嗎?  回復  更多評論
              
            狠狠人妻久久久久久综合| 亚洲欧美国产日韩综合久久| 久久免费看黄a级毛片| 久久久久久久久无码精品亚洲日韩| 日产精品99久久久久久| 国产精品青草久久久久婷婷| 国产精品久久久久乳精品爆| 色综合久久88色综合天天 | 久久亚洲私人国产精品vA| 久久精品国产亚洲Aⅴ香蕉| 久久亚洲精品无码VA大香大香| 国产成人综合久久综合| 亚洲伊人久久综合影院| 久久99免费视频| 精品久久久无码人妻中文字幕| 日本道色综合久久影院| 久久人做人爽一区二区三区 | 亚洲午夜久久影院| 亚洲精品无码久久不卡| 激情久久久久久久久久| 日韩久久久久久中文人妻 | 久久人人爽人人爽人人片AV不| 精品久久久无码人妻中文字幕豆芽| 青春久久| 久久精品国产亚洲Aⅴ蜜臀色欲| 国产成人精品久久二区二区| 中文字幕久久久久人妻| 久久久久久免费视频| 久久夜色精品国产亚洲av| 91精品免费久久久久久久久| 久久精品无码专区免费东京热| 18禁黄久久久AAA片| 久久影视综合亚洲| 久久久久久极精品久久久| 久久艹国产| 久久久久国产一区二区| 久久精品国产精品亚洲人人| 国产99久久久国产精品~~牛| 国产精品福利一区二区久久| 久久国产精品77777| 精品久久香蕉国产线看观看亚洲|