rapidxml库生成xml小例子及需注意的问题
結(jié)論:rapidxml和pugixml在生成xml方面,我建議使用pugixml,優(yōu)點(diǎn)很多,不用關(guān)心string的生命周期,像函數(shù)一樣使用添加節(jié)點(diǎn),屬性,很方便;而且效率高,個(gè)人測試了下:生成300個(gè)xml文件,pugixml用時(shí)6s,rapidxml用時(shí)60+s,效率差了10倍
如果你工作必須使用rapidxml或者換起來麻煩,那么繼續(xù)往下看,有關(guān)寫xml需要注意的一些問題
rapidxml 下載:
在官網(wǎng)上下載即可,
http://rapidxml.sourceforge.net/
https://sourceforge.net/projects/rapidxml/
得到的壓縮包里有文件如下:
讀取或者解析xml,這篇大佬寫的比較全面:
https://blog.csdn.net/v_xchen_v/article/details/75634273
這里補(bǔ)充下生成xml方面需要注意的問題:
1. 字符串的生命周期問題:每次添加節(jié)點(diǎn),string需要使用rapidxml的內(nèi)存申請函數(shù)
如果給節(jié)點(diǎn)賦值的是一個(gè)局部變量string或者char*,如果局部變量的生命周期,那么節(jié)點(diǎn)的值就會(huì)為空,建議使用rapidxml自帶的allocate_string方法來申請字符串內(nèi)存,這樣它的生命周期和節(jié)點(diǎn)的值必然是一致的了;
2. 節(jié)點(diǎn)包含中文的情況(這部分個(gè)人理解,如有不對,懇請斧正)
先說我們要寫的xml文件如下:
<book PageNumber="10"><name>小王子</name> </book>一般寫的話,還有<?xml version="1.0" encoding="utf-8"?>,這是我們常見的,同樣有 <?xml version="1.0" encoding="gbk"?>等,編碼格式聲明;
使用rapidxml,寫入字符串,有char *和wchar_t *的區(qū)別,默認(rèn)是char *
如果你用的是char*,然后節(jié)點(diǎn)包含中文,這時(shí)候聲明為:<?xml version="1.0" encoding="utf-8"?>,那么生成的xml文件在瀏覽器里會(huì)報(bào)錯(cuò),如下所示:
所以這里建議:如果你用的是char*,然后節(jié)點(diǎn)包含中文,使用<?xml version="1.0" encoding="gbk"?>這個(gè)聲明;
當(dāng)然最好的,是用wchar_t *,節(jié)點(diǎn)包含中文,就可以使用<?xml version="1.0" encoding="utf-8"?>聲明,不用擔(dān)心編碼解析問題
3. 節(jié)點(diǎn)寫入int,float等類型的值
int, float,bool需要轉(zhuǎn)換成char*字符串再寫入節(jié)點(diǎn),這里覺得使用不方便,不過還是提供下轉(zhuǎn)換的函數(shù)如下,具體見下面代碼里的Convert函數(shù)
char *方式創(chuàng)建一個(gè)包含中文格式的xml文件
#include <iostream> #include <sstream>#include "rapidxml.hpp" #include "rapidxml_utils.hpp" #include "rapidxml_print.hpp"// int , float, double等類型 轉(zhuǎn)為 std::string // bool 類型會(huì)解析成 false:0, true :1 template <typename T> std::string Convert(const T value) {using namespace std;ostringstream oss;oss << value;string str(oss.str());return str; }int main(int argc, char const *argv[]) {rapidxml::xml_document<> xml_doc;//生成 <?xml version="1.0" encoding="utf-8"?>//創(chuàng)建指向上述節(jié)點(diǎn)位置的節(jié)點(diǎn)對象rapidxml::xml_node<>* rot = xml_doc.allocate_node(rapidxml::node_pi, xml_doc.allocate_string("xml version='1.0' encoding='gbk'"));xml_doc.append_node(rot);rapidxml::xml_node<>* root_node = xml_doc.allocate_node(rapidxml::node_element, xml_doc.allocate_string("book"));// 寫入int, float等值需要先轉(zhuǎn)成string類型再寫入int count = 10;char *pageNum_str = xml_doc.allocate_string(Convert(count).c_str());rapidxml::xml_attribute<>* attr_pageNum = xml_doc.allocate_attribute(xml_doc.allocate_string("PageNumber"), pageNum_str);root_node->append_attribute(attr_pageNum);rapidxml::xml_node<>* name_node = xml_doc.allocate_node(rapidxml::node_element, xml_doc.allocate_string("name"), xml_doc.allocate_string("小王子"));root_node->append_node(name_node);xml_doc.append_node(root_node);// 先得到std::string sOut;rapidxml::print(std::back_inserter(sOut), xml_doc, 0);std::cout << sOut << std::endl;// 保存xml文件 std::string file_name("rapidxml_example.xml");// C++ 流式寫入文件std::ofstream pagefile(file_name);pagefile << sOut;pagefile.close();return 0; }wchar_t方式創(chuàng)建一個(gè)包含中文格式的xml文件
#include <iostream> #include <sstream>#include "rapidxml.hpp" #include "rapidxml_utils.hpp" #include "rapidxml_print.hpp"template <typename T> std::wstring Convert(const T Num) {using namespace std;wostringstream oss;oss << Num;wstring str(oss.str());return str; }// std::wstring 轉(zhuǎn) std::string std::string ws2s(const std::wstring &ws) {size_t i;std::string curLocale = setlocale(LC_ALL, NULL);setlocale(LC_ALL, "chs");const wchar_t* _source = ws.c_str();size_t _dsize = 2 * ws.size() + 1;std::unique_ptr< char[] > buff(new char[_dsize]);memset(buff.get(), 0x0, _dsize);wcstombs_s(&i, buff.get(), _dsize, _source, _dsize);std::string result = buff.get();setlocale(LC_ALL, curLocale.c_str());return result; }// std::string 轉(zhuǎn) std::wstring std::wstring s2ws(const std::string &s) {size_t i;std::string curLocale = setlocale(LC_ALL, NULL);setlocale(LC_ALL, "chs");const char* _source = s.c_str();size_t _dsize = s.size() + 1;std::unique_ptr< wchar_t[] > buff(new wchar_t[_dsize]);wmemset(buff.get(), 0x0, _dsize);mbstowcs_s(&i, buff.get(), _dsize, _source, _dsize);std::wstring result = buff.get();setlocale(LC_ALL, curLocale.c_str());return result; }// using namespace std; int main(int argc, char const *argv[]) {rapidxml::xml_document<wchar_t> xml_doc;//生成 <?xml version="1.0" encoding="utf-8"?>//創(chuàng)建指向上述節(jié)點(diǎn)位置的節(jié)點(diǎn)對象rapidxml::xml_node<wchar_t>* rot = xml_doc.allocate_node(rapidxml::node_pi, xml_doc.allocate_string(L"xml version='1.0' encoding='utf-8'"));xml_doc.append_node(rot);rapidxml::xml_node<wchar_t>* root_node = xml_doc.allocate_node(rapidxml::node_element, xml_doc.allocate_string(L"book"));// 寫入int, float等值需要先轉(zhuǎn)成string類型再寫入int count = 10;wchar_t *pageNum_str = xml_doc.allocate_string(Convert(count).c_str());rapidxml::xml_attribute<wchar_t>* attr_pageNum = xml_doc.allocate_attribute(xml_doc.allocate_string(L"PageNumber"), pageNum_str);root_node->append_attribute(attr_pageNum);rapidxml::xml_node<wchar_t>* name_node = xml_doc.allocate_node(rapidxml::node_element, xml_doc.allocate_string(L"name"), xml_doc.allocate_string(L"小王子"));root_node->append_node(name_node);xml_doc.append_node(root_node);// 先得到std::wstring sOut;rapidxml::print(std::back_inserter(sOut), xml_doc, 0);std::wcout.imbue(std::locale("chs"));std::wcout << sOut << std::endl;// 保存xml文件 std::string file_name("rapidxml_wchar_example.xml");// C 庫函數(shù)寫入文件,可以確保文件編碼為utf-8std::wstring wfilename = s2ws(file_name);FILE * fp = _wfsopen(wfilename.c_str(), L"a+,ccs=UTF-8", _SH_DENYNO);if (fp == NULL){printf("err\n");}int num = fwprintf_s(fp, L"%s", sOut.c_str());fclose(fp);return 0; }總結(jié)
以上是生活随笔為你收集整理的rapidxml库生成xml小例子及需注意的问题的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 第一次安装和接触RubyonRails
- 下一篇: opengl+qt+vs学习笔记1:软件