TinyXML 2.6.2 參考文檔
TinyXML是一個簡潔的、可以很容易嵌入別的程序的C++ XML解析器。
能夠做什麼
簡單地說,TinyXML可以解析一個XML文檔,並將此文檔編輯成爲一個文檔對象模型(DOM),可以方便閱讀、編輯與保存。
XML(擴展標記語言,eXtensible Markup Language)准許你定義屬於自己的文檔標記。HTML爲瀏覽器的做了非常多得工作。XML准許你定義任何類型的文檔標記,例如一個描述管理應用的”to do”列表。XML是一個結構化的、便捷的格式。所有爲了存儲應用程序數據的非常隨意的文件格式都可以被XML取代。可以這麼說TinyXML可以解析所有的文檔。
最全面、最正確和最權威的參考網站: http://www.w3.org/TR/2004/REC-xml-20040204/。對XML的介紹(我非常喜歡)的網站:http://skew.org/xml/tutorial.
有很多方法去訪問以及與XML交互數據。TinyXML使用文檔對象模型(DOM),即XML數據被解析成C++對象,這樣很容易瀏覽、操作或者被寫入磁盤以及其他數據流。你當然也可以將XML的草稿文檔寫入C++對象以及保存到磁盤以及其他的數據流。
由於TinyXML在ZLib協議下發布的,你可以在開發源代碼以及商業代碼中使用它。關於這個協議的詳細信息,可以參考任何源碼文件的最前部。
TinyXML的目的是成爲一個靈活的解析器,並且可以輸出正確合理的XML文檔。TinyXML可以在任何合理的C++編譯系統上編譯。它並不依賴異常與RTTI。它可以被編譯成支持或者不支持STL的不同版本。TinyXML完美支持UTF-8編碼和64k字符集。
不能做什麼
TinyXML不能解析或者使用DTDs(DocumentType Definitions)或者XSLs(eXtensible StylesheetLanguage)。有別的解析器去解析它們(可以在www.sourceforge.org中搜索”XML”)。但是它們要大的多,並且需要長時間的項目設置、長時間的學習以及更多嚴格的協議約束。TinyXML並不適合於從事瀏覽器開發或者其他對XML要求更全面的人。
下面的DTD語句並不能在當前的TinyXML中被解析:
<!DOCTYPE Archiv [
<!ELEMENT Comment (#PCDATA)>
]>
TinyXML會將此看會!DOCTYPE節點,但是嵌入了一個錯誤的!ELEMENT節點。這些將在下面提及。
教程
對於沒有耐心的人,下面的教程可以幫助你。一個非常適合於入門,並且非常值得你通篇閱讀的參考文檔。
代碼現狀
TinyXML是一個成熟的,經過測試的代碼。它非常穩定。如果你發現任何bug,請在sourceforge網站上(www.sourceforge.net/projects/TinyXML)寫一個bug報告,以方面我們立即獲知它們。
相關項目
TinyXML項目或許對你非常有用!
TinyXPath(http://tinyxpath.sourceforge.net).一個用C++編寫的小型的XPath語法解碼器
TinyXML++(http://code.google.com/p/ticpp/)。TinyXML++對於TinyXML來說是一個全新的接口,它使用了很多C++知識:模版、異常處理和更健全的錯誤處理機制。
特點
使用STL
TinyXML可以被編譯成支持或者不支持STL的不同版本。一旦使用STL,TinyXML可以使用std::string類,完美支持std::istream, std::ostream,operator<<和operator>>。很多API方法有”const char*”與”conststd::string&”兩中格式。
當被編譯成非STL版本時,沒有STL文件被引用.所有的string類都被替換爲TinyXML定義的類.所有的API方發都是用”constchar*”類型。
使用如下的編譯時宏定義去控制編譯哪個版本。
TIXML_USE_STL
可以通過傳遞此宏給編譯器或者在”TinyXML.h“文件的第一行定義該宏的方法。
注意:如果你在Linux下編譯測試代碼,設置環境變量TINYXML_USE_STL=YES/NO可以控制是否支持STL。在Windows的項目文件中,STL與非STL的目標配置都已經提供了。
UTF-8
TinyXML支持UTF-8,這就准許處理任何語言的XML文件。TinyXML也支持所謂的”遺傳模式”----一種在UTF-8模式被支持之前的編碼方式,或者可以被描述爲”擴展ASCII“。
TinyXML在正常情況下會嘗試檢測並且使用正確的編碼方式。然而,通過設置在頭文件中TIXML_DEFAULT_ENCODING的值,TinyXML可以被強制指定使用一種編碼方式。
TinyXML將假定使用“遺傳模式”,直到下面的情況發生:
1. 如果文件或者數據流以非標準但是卻通用的UTF-8開始字符(0xef 0xbb 0xbf)開頭,TinyXML將使用UTF-8模式。
2. 如果聲明標記被讀到,並且指定爲UTF-8,TinyXML將使用UTF-8模式。
3. 如果聲明標記被讀到,並且沒有指定任何模式,TinyXML將使用UTF-8模式。
4. 如果聲明標記被讀到,並且被指定爲未識別的模式(somethingelse),TinyXML將使用遺傳模式。在遺傳模式下,TinyXML會按照以前的模式工作。它並不清楚是哪種具體的模式,但是久的內容將會正常工作。
5. 直到上面的任何一種規則被遇到,否則TinyXML會按照遺傳模式工作。
當編碼方式沒有被正確地設置或者檢測到會發生什麼呢?TinyXML將嘗試去讀並且忽略非正常編碼的文本。你或許會得到奇怪的結果或者損壞的字符。你或者想強制TinyXML使用正確的模式。
你可以通過LoadFile(TIXML_ENCODING_LEGACY)或者LoadFile(filename, TIXML_ENCODING_LEGACY)接口強制TinyXML使用遺傳模式。你也可以通過設置TIXML_DEFAULT_ENCODING = TIXML_ENCODING_LEGACY強制TinyXML在任何時候都使用遺傳模式。當然,你也可以通過同樣的方法設置強制TinyXML使用TIXML_ENCODING_UTF8模式。
針對英語用戶,使用英文版的TinyXML,UTF-8與low-ASCII類似。你並不需要關注UTF-8或者改變你的編碼方式。你僅僅需要把UTF-8爲ASCII的超集。
UTF-8並不是雙字符模式-但是它是Unicode的標準編碼模式!TinyXML在當前並不使用或者直接支持wchar,TCHAR或者微軟的_UNICODE。這些編碼方式有點複雜,老代碼和老操作系統趨向於使用”默認的“或者”傳統的“代碼頁。許多應用(並且幾乎所有的現代版本)都可以輸出UTF-8,但是舊的或者頑固的(或者僅僅被打斷的)應用還用默認的方式輸出代碼頁。
例如,日文版的系統傳統上使用SHIFT-JIS編碼方式。按照SHIFT-JIS模式編碼的文本並不會被TinyXML正確讀取。一個優秀的文本編輯器支持將SHIFT-JIS編碼的文本導入,然後另存爲UTF-8模式。
Skew.org爲編碼問題做了大量的工作。
測試文件”utf8test.xml”是一個包含英文、西班牙文、俄文和簡體中文的XML文檔。(真希望它們能夠正確翻譯)“utf8test.gif“是該文件的截圖,可以在IE上顯示。值得注意的是:如果你的系統沒有正確的字符(簡體中文或者俄文),你將不會看到如GIF圖片上的顯示即使解析正確。更要注意(至少在我的Windows機器上)控制檯以西文編碼方式顯示,所以Print()或者printf()並不能正常顯示該文件。這並不是TinyXML的bug-僅僅是操作系統的問題。並沒有數據被TinyXML丟失或者破壞。控制檯並不能顯示UTF-8編碼方式。
實體(Entities)
TinyXML識別預定義的“字符實體”爲特殊字符,即:
& &
< <
> >
" "
' '
當XML文檔被讀取的時候它們被識別,並且被翻譯成等效的UTF-8模式。例如,XML文本:
Far& Away
查詢TiXmlText對象的Value()方法時,將擁有”Far & Away“,並且以&將被寫回XML流/文件。舊版本的TinyXML會保留這些字符實體,但是新版本會將它們翻譯成字符。
另外,任何字符都可以通過Unicode編碼的標點指定。如語法”
”或者“ ”都會被翻譯爲非破裂的空字符。
打印(Printing)
TinyXML可以以多種方式打印結果,有長處也有限制。
Print(FILE*):輸出爲標準C數據流,包括所有的C文件和stdout。
> “完美打印“,你並不能控制打印選項
> 結果直接以流的方式輸出到FILE對象,TinyXML並沒有內存開銷。
> 使用Print()與SaveFile()方法
operator<<:輸出爲C++流
> 與標準C++流集成
> 網絡打印模式打印的結果中沒有換行符。方便網絡傳輸和在C++對象間傳遞XML,並不適合人類閱讀。
TiXmlPrinter:輸出爲std::string或內存緩衝區
> API不簡明
> 將來的打印控制可以放在這裏
> 打印方法將來只需少量的改變就得以改善與擴展
流(Streams)
通過設置TIXML_USE_STL,TinyXML可以像支持C流(FILE*)一樣支持C++流(operator<<, >>)。有寫不同點值得你關注。
C格式輸出:
基於FILE*
通過Print()與SaveFile()方法
爲了儘可能具有可讀性,它產生具有大量空白字符的格式化輸出結果。這種方式非常快,並且具有XML文檔的容錯性。例如,一個具有2個根節點與2個聲明的XML文檔同樣也可以直接打印。
C格式輸入:
基於FILE*
通過Parse()與LoadFile()方法
一個快速並且具有容錯性的讀操作。在不需要C++流的時候使用。
C++格式輸出:
基於std::stream
operator<<
爲了方便網絡傳輸而不是可讀性,產生壓縮性的輸出結果。依靠你的系統對於ostream類的實現,這種方法或許有些慢(或者並不慢)。不具有XML的容錯性:文檔必須包含一個根節點。另外,根節點級別的其餘元素都不會被輸出。
C++格式輸入:
基於std::istream
operator>>
從數據流讀入XML,使它方便網絡傳輸。複雜的地方是:當沒有別的數據在流中時,就認爲XML文檔結束。然而,TinyXML假定在讀完根節點元素時就認定XML數據結束。即,如果文檔錯誤地構造爲包含不止一個根節點時就不能正確地被讀取。注意:由於STL的實現方法與TinyXML的限制,operator>>在很大程度上比Parse接口慢。
空白字符(White Space)
這個世界針對空白字符是否需要保留與壓縮並沒有達成一致。例如,假設‘_’是一個空格,現在來看”Hello____world”。HTML與至少一些XML解析器,將它解析爲“Hello_world”。他們壓縮了空白字符。一些XML解析器並不壓縮,而將之保留爲“Hello____wrld”。(注意假設_爲空格)另外一些解析器建議將__Hello____world__解析爲Hello____world。
這些並不能使我滿足。TinyXML支持頭2中方法。調用TiXmlBase::SetCondenseWhiteSpace(bool)來設置期望的方式。默認設置爲壓縮空白字符。
如果你想改變默認方式,你需要在調用任何解析XML數據之前調用TiXmlBase::SetCondenseWhiteSpace(bool)。我並不推薦在之後調用該方法。
句柄(Handles)
當隨意瀏覽XML文檔時,檢測調用方法的返回結果是否爲null是很有必要的。一個容錯的安全實現需要產生大量的代碼,如下:
TiXmlElement* root = document.FirstChildElement( "Document" );
if ( root )
{
TiXmlElement* element = root->FirstChildElement( "Element" );
if ( element )
{
TiXmlElement* child = element->FirstChildElement( "Child" );
if ( child )
{
TiXmlElement* child2 = child->NextSiblingElement( "Child" );
if ( child2 )
{
// Finally do something useful
句柄可以將這些代碼清除掉。使用TiXmlHandle類,上面的代碼可以削減爲:
TiXmlHandle docHandle( &document );
TiXmlElement* child2 = docHandle.FirstChild( "Document" ).FirstChild( "Element" ).Child( "Child", 1 ).ToElement();
if ( child2 )
{
// do something useful
這更容易處理。查看TiXmlHandle類瞭解更多。
行與列跟蹤(Row and Column Tracking)
能夠知道節點與屬性在源文件中的原始位置對於應用程序來說是非常必要的。另外,知道在源文件的何處解析錯誤非常節省時間。
TinyXML能夠跟蹤文本文件中任何節點或屬性的行與列的位置。TiXmlBase::Row()與TiXmlBase::Column()方法將返回節點在源文件中的原始位置。正確製表符可以通過TiXmlDocument::SetTabSize()去設定。
使用與安裝(Using and Installing)
編譯與運行xmltest:
源碼中提供了Linux的Makefile文件與Windows的C++ .dsw文件。簡單地編譯並且運行。將會在你的磁盤上寫產生demotest.xml文件並且在屏幕上顯示結果。它能夠以多種方式打遍歷DOM(文檔對象模型)並打印節點數。
Linux makefile文件是非常通用的並且可以在多種系統上執行 – 當前只在mingw和MacOSX上測試。你並不需要執行’make depend‘。依賴關係是被寫死的(hard coded)。
Windows下的VC6項目文件
TinyXML:TinyXML庫,非STL版本
TinyXMLSTL:TinyXML庫,STL版本
TinyXMLTest:測試程序,非STL版本
TinyXMLTestSTL:測試程序,STL版本
Makefile
在該文件的頭部你可以設置:
PROFILE,DEBUG與TINYXML_USE_STL。更詳細的內容(像你們看到的一樣)在makefile中。
在TinyXML目錄中,先執行“make clean”,然後執行“make”。這樣就會產生名爲“xmltest”的可執行文件。
在應用程序中使用(To User in an Application)
在你的項目文件或者make文件中添加TinyXML.cpp,TinyXML.h,TinyXMLerror.cpp,TinyXMLparser.cpp,tinystr.cpp與tinystr.h!這就是全部。這就可以在任何合理的C++編譯系統上編譯。你並不需要爲TinyXML打開異常與RTTI。
TinyXML是如何工作的(How TinyXML works)
一個例子或許是最好的開始方法。例如:
<?xml version="1.0" standalone=no>
<!-- Our to do list data -->
<ToDo>
<Item priority="1"> Go to the <bold>Toy store!</bold></Item>
<Item priority="2"> Do bills</Item>
</ToDo>
它並沒有過多的To Do列表,但是完全可以說明問題。爲了讀取這個文件(demo.xml),你需要創建一個文檔並且解析它:
TiXmlDocument doc( "demo.xml" );
doc.LoadFile();
它開始工作了。現在讓我們來看看一些行,並且看看他們是如何關聯DOM的。
<?xml version="1.0" standalone=no>
文檔的第一行,將被轉換成TiXmlDeclaration類。它將會是文檔節點的第一個孩子。
這是僅有的被TinyXML解析的指令/特殊標記。通常指令標記被保存在TiXmlUnknown類中,所以這些指令不會被漏寫入磁盤。
<!-- Our to do list data -->
註釋。會被解析成TiXmlComment對象。
<ToDo>
“ToDo”標記定義了TiXmlElement對象。這個節點沒有包含任何屬性,但是包含了2個其它元素。
<Item priority="1">
創建了另一個TiXmlElement對象,它是“ToDo”元素的孩子。這個元素有1個名爲“priority”,值爲“1”的屬性。
Go to the
一個TiXmlText。這是一個葉節點,不可以擁有其它提點。它是“Item”TiXmlElement“的孩子。
<bold>
另一個TiXmlElement,它是”Item“元素的一個孩子。
等等……
現在看看整個對象樹,結束以:
TiXmlDocument "demo.xml"
TiXmlDeclaration "version='1.0'" "standalone=no"
TiXmlComment " Our to do list data"
TiXmlElement "ToDo"
TiXmlElement "Item" Attribtutes: priority = 1
TiXmlText "Go to the "
TiXmlElement "bold"
TiXmlText "Toy store!"
TiXmlElement "Item" Attributes: priority=2
TiXmlText "Do bills"
文檔(Documentation)
幫助文檔是通過Doxygen創建的,使用”doc“配置文件。
許可(License)
TinyXML在zlib許可協議下發行:
該軟件按照’as-is‘方式提供,不會有任何明確或隱含的授權。作者並不對使用該軟件承擔任何損害性的責任。
在以下的約束下,准許任何人以任何目的使用該軟件,包括:商業應用,自由地修改並且發行:
1. 軟件的原創不能夠予以錯誤的報道:你不能夠聲明你參與了原始軟件的開發工作。如果你在產品中使用該軟件,在產品文檔的致謝寫入是值得欣賞的,但並不是必須的。
2. 修改原始版本必須清楚聲明,並且不能夠被誤解爲是原始的軟件。
3. 這個通知不可以從任何源碼版本中刪除或修改。
參考(References)
萬維網組織定義了XML的標準部分,並且他們的網頁上包含了大量的參考信息。
參考頁面: http://www.w3.org/TR/2004/REC-xml-20040204/
(注:翻譯的不當之處,請指出)