RAPIDXML 中文手册,根据官方文档完整翻译!
簡(jiǎn)介:
這個(gè)號(hào)稱是最快的DOM模型XML分析器,在使用它之前我都是用TinyXML的,因?yàn)樗∏珊腿菀咨鲜?#xff0c;但真正在項(xiàng)目中使用時(shí)才發(fā)現(xiàn)如果分析一個(gè)比較大的XML時(shí)TinyXML還是表現(xiàn)一般,所以我們決定使用RapidXML作為替換。當(dāng)然是為了獲取更好的性能,經(jīng)過我們的初步試驗(yàn)后發(fā)現(xiàn)確實(shí)比TinyXML好,但看到網(wǎng)上關(guān)于rapidxml的資料零散,而且也缺乏一份較為權(quán)威的說明文檔,找來找去還是得看官方的英文手冊(cè)。所以我又下單了,翻譯官方提供的手冊(cè),希望給各位朋友提供一些綿薄之力。
1. RapidXml 是什么?
RapidXML是一個(gè)試圖創(chuàng)建最快的XML DOM分析器,當(dāng)然同時(shí)也保留它的可用性、移植性和適當(dāng)?shù)腤3C兼容性。它是一個(gè)用C++編寫的即用分析器,在相同的數(shù)據(jù)上它的分析速度接近于strlen()函數(shù)。
整個(gè)分析器就包含在單獨(dú)的一個(gè)頭文件中,所以不需要任何的構(gòu)建和鏈接。當(dāng)你使用的時(shí)候只需將 rapidxml.hpp 文件復(fù)制到一個(gè)合適的地方(例如你的工程目錄下),然后在任何需要它的地方包含一下即可?;蛟S你也會(huì)用到 rapidxml_print.hpp 頭文件里的打印函數(shù)。
1.1 Dependencies And Compatibility(依賴和兼容)
RadpidXML除了使用到標(biāo)準(zhǔn)C++庫(kù)(<cassert>, <cstdlib>, <new> 和 <exception>, 除非異常被關(guān)閉了)的很小一個(gè)子集外沒有關(guān)聯(lián)其它東西了。它能被任何標(biāo)準(zhǔn)編譯器所編譯,并已在Visual C++ 2003, Visual C++ 2005, Visual C++ 2008, gcc 3, gcc 4, 和 Comeau 4.3.3. 中測(cè)試通過。也就是說在這些編譯器上沒出現(xiàn)任何的警告信息,即使在最高警告級(jí)別上。
1.2 Character Types And Encodings(字符類型和編碼)
RadpidXML并不知道字符集的類型(譯注:因?yàn)樗腔谀0?#xff0c;可以自定義字符類型),所以在窄字符和寬字符下都能工作。當(dāng)前版本并不完全支持UTF-16和UTF-32,所以使用寬字符稍微有點(diǎn)不適合。不管怎樣,如果數(shù)據(jù)的字節(jié)順序與當(dāng)前系統(tǒng)匹配,它能成功分析包含UTF-16或UTF-32 的wchar_t 字符串。UTF-8是完全支持的,包括所有的數(shù)值字符引用,這些字符會(huì)被擴(kuò)展到適當(dāng)?shù)腢TF-8字節(jié)順序(除非你打開parse_no_utf8 flag 標(biāo)記)。
要注意RapidXml不會(huì)對(duì) name() 和 value() 函數(shù)返回的字符串進(jìn)行解碼,因?yàn)楹瘮?shù)會(huì)根據(jù)源代碼文件本身的編碼模式來編碼(譯注:也就是說如果你的源代碼文件編碼格式為ANSI,則name()函數(shù)返回的字符串編碼也是ANSI,如果源代碼文件的編碼格式為UTF-8,字符串編碼也是UTF-8)。Rapidxml能解釋和擴(kuò)展下列的字符應(yīng)用:' & " < > &#...;其它字符引用不會(huì)被展開。
1.3 Error Handling (錯(cuò)誤處理)
默認(rèn)情況下,RapidXml使用C++異常來報(bào)告錯(cuò)誤,如果你不喜歡這個(gè)行為,可以使用RAPIDXML_NO_EXCEPTIONS定義來制止異常代碼,請(qǐng)參考 parse_error 類和 parse_error_handler() (http://rapidxml.sourceforge.net/manual.html#namespacerapidxml_ff5d67f74437199d316d2b2660653ae1_1ff5d67f74437199d316d2b2660653ae1) 函數(shù)。
1.4 Memory Allocation(內(nèi)存分配)
RadpidXml使用一個(gè)特別的內(nèi)存池對(duì)象來分配所有的節(jié)點(diǎn)和屬性,因?yàn)橹苯邮褂?new 操作符來分配太慢了,池中的內(nèi)存分配可用 memory_pool::set_allocator() (http://rapidxml.sourceforge.net/manual.html#classrapidxml_1_1memory__pool_c0a55a6ef0837dca67572e357100d78a_1c0a55a6ef0837dca67572e357100d78a) 函數(shù)來自定義,詳細(xì)信息請(qǐng)看 memory_pool (http://rapidxml.sourceforge.net/manual.html#classrapidxml_1_1memory__pool) 類。
1.5 W3C Compliance(W3C兼容)
RapidXml并不是一個(gè)與W3C完全一致的分析器,主要原因是忽略了 DOCTYPE 聲明。還有一些其它原因,如兼容性不是很好,但是,它能成功分析和生成與W3C文件組(有關(guān)XML處理器的規(guī)格設(shè)計(jì)超過1000個(gè)文件)定義的完整XML樹。即使在不良的情況下它也能對(duì)空白符進(jìn)行正?;幚砗蛯?duì)一部分字符集實(shí)體進(jìn)行替換。
1.6 API Design(API設(shè)計(jì))
為了盡可能的減少代碼量,RadpidXML API已經(jīng)很簡(jiǎn)約了,并且為了能在它嵌入的環(huán)境中更容易使用,一些附加的功能被分割在不同的頭文件中:rapidxml_utils.hpp 和rapidxml_print.hpp (http://rapidxml.sourceforge.net/manual.html#rapidxml__print_8hpp)。這兩個(gè)頭文件并不是必須的,并且當(dāng)前也沒有相關(guān)文檔(但是代碼中有注釋)。
1.7 Reliability(可靠性)
RadpidXML很健壯,因?yàn)樗ㄟ^了一大堆的單元測(cè)試。已經(jīng)特別小心地確保分析器的穩(wěn)定性,不管你扔什么文本給它。其中的一項(xiàng)單元測(cè)試用了隨機(jī)產(chǎn)生100,000個(gè)XML文檔錯(cuò)誤,RapidXml也能創(chuàng)建它(還未更正)。當(dāng)這些錯(cuò)誤被引入后RapidXml還是能通過這項(xiàng)測(cè)試,并且不會(huì)被破壞和進(jìn)入死循環(huán)。
其它的單元測(cè)試也和RapidXMl進(jìn)行肉搏,穩(wěn)定的XML分析器,和其它為了符合一大推文檔和功能的測(cè)試。
另外RapidXml進(jìn)行了1000多個(gè)W3C兼容性文件測(cè)試,并且都能取得正確的結(jié)果。其它的測(cè)試包括對(duì)API函數(shù)的測(cè)試,并且測(cè)試各種各樣的分析模式。
1.8 Acknowledgements(致謝)
I would like to thank Arseny Kapoulkine for his work on pugixml (http://code.google.com/p/pugixml), which was an inspiration for this project. Additional thanks go to Kristen Wegner for creating pugxml (http://www.codeproject.com/soap/pugxml.asp), from which pugixml was derived. Janusz Wohlfeil kindly ran RapidXml speed tests on hardware that I did not have access to, allowing me to expand performance comparison table.
2. Two Minute Tutorial(兩分鐘教程)
2.1 Parsing(分析)
下面的代碼示范了RapidXml分析一個(gè)以0結(jié)尾的字符串text:
using namespace rapidxml;
xml_document<> doc; // 字符類型默認(rèn)為char
doc.parse<0>(text); // 0表示默認(rèn)分析標(biāo)記
doc對(duì)象現(xiàn)在是一個(gè)DOM樹,代表已分析的XML。因?yàn)樗械腞adpidXml接口都包含在命名空間 rapidxml中,用戶要么加入此命令空間,要么使用完整的命名(譯注:即要使用doc必須使用 rapidxml::xml_docment<> doc),類xml_document代表一個(gè)DOM層次的根節(jié)點(diǎn)。除了是公共的繼承點(diǎn),它還是一個(gè)xml_node 和memory_pool。xml_document::parse()函數(shù)的模板參數(shù)是用來指定分析標(biāo)記的,它可以用來對(duì)分析器進(jìn)行微調(diào)。但要注意,標(biāo)記必須是一個(gè)編譯器的常數(shù)。
2.2 Accessing The DOM Tree(訪問DOM樹)
要訪問DOM樹,使用xml_node和xml_attribute類中的方法即可:
cout << "Name of my first node is: " << doc.first_node()->name() << "\n";
xml_node<> *node = doc.first_node("foobar");
cout << "Node foobar has value " << node->value() << "\n";
for (xml_attribute<> *attr = node->first_attribute();
attr; attr = attr->next_attribute())
{
cout << "Node foobar has attribute " << attr->name() << " ";
cout << "with value " << attr->value() << "\n";
}
2.3 Modifying The DOM Tree(修改DOM樹)
分析器生成的DOM樹完全可以修改??梢栽黾雍蛣h除節(jié)點(diǎn)和屬性,還有他們的內(nèi)容。下面的例子創(chuàng)建了一個(gè)HTML文檔,并有個(gè)單獨(dú)的鏈接到google.com網(wǎng)站:
xml_document<> doc;
xml_node<> *node = doc.allocate_node(node_element, "a", "Google");
doc.append_node(node);
xml_attribute<> *attr = doc.allocate_attribute("href", "google.com");
node->append_attribute(attr);
其中一個(gè)特點(diǎn)是節(jié)點(diǎn)和屬性都不擁有它們的名稱和值。這是因?yàn)橥ǔK鼈兌贾槐4嬷赶蛟次谋镜闹羔槨K?#xff0c;當(dāng)關(guān)聯(lián)一個(gè)新的名稱或值給節(jié)點(diǎn)時(shí),要特別小心字符串的生命周期。最簡(jiǎn)單的方法是通過xml_document內(nèi)存池來分配字符串。在上面的例子中其實(shí)是不需要的,因?yàn)槲覀冎魂P(guān)聯(lián)了字符常量。但是下面的例子就使用memory_pool::allocate_string() (http://rapidxml.sourceforge.net/manual.html#classrapidxml_1_1memory__pool_69729185bc59b0875192d667c47b8859_169729185bc59b0875192d667c47b8859)函數(shù)來分配節(jié)點(diǎn)名稱(擁有與文檔一樣的生命周期),并將它關(guān)聯(lián)到一個(gè)新的節(jié)點(diǎn):
xml_document<> doc;
char *node_name = doc.allocate_string(name); // 分配字符串并將名稱復(fù)制進(jìn)去
xml_node<> *node = doc.allocate_node(node_element, node_name); // 為 node_name設(shè)置節(jié)點(diǎn)名稱
查看 參考 小節(jié)可看到這個(gè)接口的描述。
2.4 Printing XML(打印XML)
你可以將xml_document和xml_node對(duì)象輸出為一個(gè)XML字符串。使用print()函數(shù)或操作符 operator<<,在 rapidxml_print.hpp (http://rapidxml.sourceforge.net/manual.html#rapidxml__print_8hpp) 頭文件中可找到這些定義。
using namespace rapidxml;
xml_document<> doc; // 字符類型默認(rèn)為 char
// ... 一些填充文檔的代碼
// 使用標(biāo)準(zhǔn)字符流operator <<
std::cout << doc;?
// 用print函數(shù)來輸出流,指定了打印參數(shù)
print(std::cout, doc, 0); // 0 表示默認(rèn)
// 通過輸出迭代器來打印字符串
std::string s;
print(std::back_inserter(s), doc, 0);
// 通過輸出迭代器來輸出到內(nèi)存緩存里
char buffer[4096]; // 你必須保證緩存足夠大!
char *end = print(buffer, doc, 0); // end包含了指向最后一個(gè)字符的指針
*end = 0; // 在XML后面添加字符終止符
3. Differences From Regular XML Parsers(與常規(guī)XML分析器的不同之處)
RapidXml是一個(gè)原位分析器,能提供非常快的分析速度。原位的意思是分析器并不做字符串的拷貝,而是在DOM層次中放置指向源文本的指針。
3.1 Lifetime Of Source Text(源文本的生命周期)
原位分析需要源文本的生命周期與XML文檔對(duì)象一樣長(zhǎng)。如果源文本銷毀了,DOM樹里的節(jié)點(diǎn)名稱和值也會(huì)跟著銷毀,而且,空白符處理,字符集轉(zhuǎn)換,和0結(jié)尾的字符串都需要在分析期間被修改(但不是破壞性的)。這就使得Rapidxml進(jìn)行下一步分析時(shí)字符串不再有效了。
但是在大多數(shù)情況下,這些都不是嚴(yán)重的問題。
3.2 Ownership Of Strings(字符串的所有權(quán))
Rapidxml生成的節(jié)點(diǎn)和屬性都不擁有它們自己的名稱和值字符串。它們只是保留了指向名稱和值的指針。也就是說,當(dāng)你用xml_base::name(const Ch *) (http://rapidxml.sourceforge.net/manual.html#classrapidxml_1_1xml__base_e099c291e104a0d277307fe71f5e0f9e_1e099c291e104a0d277307fe71f5e0f9e) 或 xml_base::value(const Ch *) (http://rapidxml.sourceforge.net/manual.html#classrapidxml_1_1xml__base_18c7469acdca771de9b4f3054053029c_118c7469acdca771de9b4f3054053029c) 函數(shù)時(shí)必須非常小心的設(shè)置這些值。要小心保證傳遞進(jìn)來的字符串擁有與節(jié)點(diǎn)和屬性一樣長(zhǎng)的生命周期。也可以簡(jiǎn)單地通過使用文檔的內(nèi)存池來分配這些字符串。使用memory_pool::allocate_string() (http://rapidxml.sourceforge.net/manual.html#classrapidxml_1_1memory__pool_69729185bc59b0875192d667c47b8859_169729185bc59b0875192d667c47b8859)函數(shù)可達(dá)到此目的。
3.3 Destructive Vs Non-Destructive Mode(破壞模式和非破壞模式)?
默認(rèn)情況下,當(dāng)分析器進(jìn)行分析處理時(shí)會(huì)修改源文本。這時(shí)因?yàn)樾枰鲎址霓D(zhuǎn)換、空白符常規(guī)化、字符串0終止。
可能在某些情況下這個(gè)行為不好,例如源文本在一個(gè)只讀的內(nèi)存中,或者是從文件中直接映射過來的。通過使用適當(dāng)?shù)姆治鰳?biāo)記(parse_non_destructive),源文本修改模式可以被關(guān)閉。但是,因?yàn)镽apidxml做了原位分析,該標(biāo)記明顯有下列的副作用:
· 不作空白符的正常化處理
· 不作實(shí)體引用轉(zhuǎn)換
· 名稱和值都是非0終止的,你必須使用xml_base::name_size() (http://rapidxml.sourceforge.net/manual.html#classrapidxml_1_1xml__base_0dae694c8f7e4d89f1003e2f3a15a43c_10dae694c8f7e4d89f1003e2f3a15a43c) 和 xml_base::value_size() (http://rapidxml.sourceforge.net/manual.html#classrapidxml_1_1xml__base_aed5ae791b7164c1ee5e649198cbb3db_1aed5ae791b7164c1ee5e649198cbb3db)函數(shù)來告訴他們結(jié)束。
總結(jié)
以上是生活随笔為你收集整理的RAPIDXML 中文手册,根据官方文档完整翻译!的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Hacking Diablo II之外挂
- 下一篇: windows server2003/R