rapidxml 文件读写,增加删除节点
RapidXml是指 XML DOM解析工具包,是一個快速的讀寫xml文件的庫文件(hpp)。本文旨在提供RapidXml文件讀寫操作,以及對節點的增加、刪除、編譯提供一個測試用例,以免忘記。
1. 讀取XML
#include "rapidxml.hpp" #include "rapidxml_utils.hpp" #include "rapidxml_print.hpp" #include <vector> #include <string> #include <map> #include <set> #include <iostream> #include <sstream> #include <io.h>void str2int(int& int_tmp, const std::string& string_tmp) {std::stringstream stream(string_tmp);stream >> int_tmp; }void str2float(float& float_tmp, const std::string& string_tmp) {float_tmp = atof(string_tmp.c_str()); }void splitLabels(const std::string& labels, std::vector<std::string>& splitalbelres) {std::string result;std::stringstream input(labels);while (input >> result){splitalbelres.push_back(result);} }void readFunctionParam(rapidxml::xml_node<char>* FunctionNode) {rapidxml::xml_node<char>* DeteNode = FunctionNode->first_node("Detectors");if (DeteNode != nullptr){for (rapidxml::xml_node<char>* node = DeteNode->first_node("iter"); node != nullptr; node = node->next_sibling()){std::string name = "";std::string version = "";std::string label = "";float fConfidence = 0.0;int iShowWin = 0;int iIsStandard = 0;std::set<int> setUsefulLabel;rapidxml::xml_node<>* pName = node->first_node("name");if (pName != nullptr){name = pName->value();}rapidxml::xml_node<>* pVersion = node->first_node("version");if (pVersion != nullptr){version = pVersion->value();}rapidxml::xml_node<>* pConf = node->first_node("confidence");if (pConf != nullptr){str2float(fConfidence, pConf->value());}rapidxml::xml_node<>* pShowWin = node->first_node("bshowDebugWin");if (pShowWin != nullptr){str2int(iShowWin, pShowWin->value());}rapidxml::xml_node<>* pIsStandard = node->first_node("bStandard");if (pIsStandard != nullptr){str2int(iIsStandard, pIsStandard->value());}rapidxml::xml_node<>* pUsefulLabel = node->first_node("usefulLabel");if (pUsefulLabel != nullptr){label = pUsefulLabel->value();std::vector<std::string> splitlabelres;splitLabels(label, splitlabelres);for (int i = 0; i < splitlabelres.size(); i++){setUsefulLabel.insert(std::atoi(splitlabelres[i].c_str()));}}}rapidxml::xml_node<char>* pShowreportNode = FunctionNode->first_node("ShowReportWin");if (pShowreportNode != nullptr){int iShowReportWin = 0;str2int(iShowReportWin, pShowreportNode->value());}} }void ReadParam(const rapidxml::xml_document<>& pDoc) {//獲取根節點rapidxml::xml_node<char>* root = pDoc.first_node("config");//找到采樣幀率節點int iSampleFrequency;rapidxml::xml_node<>* samplefre = root->first_node("SampleFrequency");str2int(iSampleFrequency, samplefre->value());//找到功能節點std::string sFunctionName = "SMOKEFireDetection";rapidxml::xml_node<>* intrusion = root->first_node(sFunctionName.c_str());if (intrusion != nullptr){readFunctionParam(intrusion);}}void readXMLByFile(const std::string& xmlpath) {/************************************************************************file類data() 返回 char* 的xml文本內容size() 返回 unsigned int的文本數據長度定義: rapidxml::file<0> valName("xmlpath");xml_document類parse(Ch *text) 將文本數據解析為DOM treeclear() 清空DOM tree定義: rapidxml::xml_document<0> doc;************************************************************************/try{// 用file文件讀入緩沖區rapidxml::file<> fdoc(xmlpath.c_str());// 打印從文件中讀取的內容std::cout << fdoc.data();// 解析獲取DOM實例rapidxml::xml_document<> doc;doc.parse<0>(fdoc.data());ReadParam(doc);doc.clear();}catch (rapidxml::parse_error e){std::cout << e.what() << std::endl;return;}}static const int buf_len = 2048; static char buf[buf_len] = { 0 }; void readXMLByStream(const std::string& xmlpath) {try{// 清空緩沖區memset(buf, 0, buf_len);// 判斷文件是否存在if (_access(xmlpath.c_str(), 0) == -1){std::cout << "xml file " << xmlpath << "is not exits!" << std::endl;return;}// 實例化文件讀取流std::ifstream infile(xmlpath, std::ios::in);if (!infile){std::cout << "file stream instance error!" << std::endl;return;}// 讀取文件內容到緩沖區infile.read(buf, buf_len);// 輸出文件內容std::cout << buf << std::endl;// 實例化DOMrapidxml::xml_document<> doc;doc.parse<0>(buf);ReadParam(doc);doc.clear();infile.close();}catch (rapidxml::parse_error e){std::cout << e.what() << std::endl;return;}}void main() {std::string xmlpath = "ReadExample.xml";readXMLByFile(xmlpath);readXMLByStream(xmlpath);std::system("pause");}其對應的xml文件如下所示:
<config> <SampleFrequency>25</SampleFrequency><SMOKEFireDetection><Detectors><iter><name>fire</name><version>1.3.0</version><confidence>0.5</confidence><bshowDebugWin>1</bshowDebugWin><usefulLabel>3 4 5</usefulLabel><bStandard>1</bStandard></iter><iter><name>smoke</name><version>1.6.0</version><confidence>0.2</confidence><bshowDebugWin>1</bshowDebugWin><usefulLabel>4</usefulLabel><bStandard>1</bStandard></iter><iter><name>motionanalyze</name><version></version><confidence></confidence><bshowDebugWin>1</bshowDebugWin><usefulLabel></usefulLabel></iter></Detectors><ShowReportWin>1</ShowReportWin> </SMOKEFireDetection></config>2. 創建XML文件
#include "rapidxml.hpp" #include "rapidxml_utils.hpp" #include "rapidxml_print.hpp" #include <iostream> #include <string> #include <fstream> #include <io.h> #include <stdlib.h>void CreateXml(const std::string& XMLFileName) {//保存Annotation, 把識別結果寫進xml// DOMrapidxml::xml_document<> doc;// node_declaration//rapidxml::xml_node<>* declaration = doc.allocate_node(rapidxml::node_declaration);//declaration->append_attribute(doc.allocate_attribute("version", "1.0"));//declaration->append_attribute(doc.allocate_attribute("encoding", "utf-8"));//doc.append_node(declaration);// node_pirapidxml::xml_node<>* root = doc.allocate_node(rapidxml::node_pi, doc.allocate_string("xml version='1.0' encoding='utf-8'"));doc.append_node(root);// node_commentrapidxml::xml_node<>* comment = doc.allocate_node(rapidxml::node_comment, 0, " 這是對目標的Annotation保存格式 ");doc.append_node(comment);// node_element rapidxml::xml_node<>* node = doc.allocate_node(rapidxml::node_element, "annotation", "information");doc.append_node(node);// node_datarapidxml::xml_node<>* folder = doc.allocate_node(rapidxml::node_element, "folder", "VOC2007");node->append_node(folder);rapidxml::xml_node<>* filename = doc.allocate_node(rapidxml::node_element, "filename", XMLFileName.c_str());node->append_node(filename);// node_element with valuerapidxml::xml_node<>* source = doc.allocate_node(rapidxml::node_element, "source", nullptr);source->append_node(doc.allocate_node(rapidxml::node_element, "database", "My VOC2007 Databas"));source->append_node(doc.allocate_node(rapidxml::node_element, "annotation", "VOC2007"));source->append_node(doc.allocate_node(rapidxml::node_element, "image", "flickr"));source->append_node(doc.allocate_node(rapidxml::node_element, "flickrid", "nullptr"));node->append_node(source);rapidxml::xml_node<>* owner = doc.allocate_node(rapidxml::node_element, "owner", nullptr);owner->append_node(doc.allocate_node(rapidxml::node_element, "flickrid", "nullptr"));owner->append_node(doc.allocate_node(rapidxml::node_element, "name", "aware"));node->append_node(owner);rapidxml::xml_node<>* size = doc.allocate_node(rapidxml::node_element, "size", nullptr);int width = 1920;char cw[128];_itoa_s(width, cw, 128, 10);size->append_node(doc.allocate_node(rapidxml::node_element, "width", cw));int height = 1080;char ch[128];_itoa_s(height, ch, 128, 10);size->append_node(doc.allocate_node(rapidxml::node_element, "height", ch));size->append_node(doc.allocate_node(rapidxml::node_element, "depth", "3"));node->append_node(size);rapidxml::xml_node<>* segmented = doc.allocate_node(rapidxml::node_element, "segmented", "0");node->append_node(segmented);for (int i = 0; i < 2; i++){// node_commentrapidxml::xml_node<>* comment = doc.allocate_node(rapidxml::node_comment, 0, " 目標的位置狀態信息 ");node->append_node(comment);rapidxml::xml_node<>* object = doc.allocate_node(rapidxml::node_element, "object", nullptr);node->append_node(object);object->append_node(doc.allocate_node(rapidxml::node_element, "name", doc.allocate_string("example")));object->append_node(doc.allocate_node(rapidxml::node_element, "pose", "Unspecified"));object->append_node(doc.allocate_node(rapidxml::node_element, "truncated", "0"));object->append_node(doc.allocate_node(rapidxml::node_element, "difficult", "0"));rapidxml::xml_node<>* bndbox = doc.allocate_node(rapidxml::node_element, "bndbox", nullptr);object->append_node(bndbox);bndbox->append_node(doc.allocate_node(rapidxml::node_element, "xmin", "11"));bndbox->append_node(doc.allocate_node(rapidxml::node_element, "ymin", "20"));bndbox->append_node(doc.allocate_node(rapidxml::node_element, "xmax", "1000"));bndbox->append_node(doc.allocate_node(rapidxml::node_element, "ymax", "600"));//打印整個XML內容std::string text;rapidxml::print(std::back_inserter(text), doc, 0);std::cout << text << std::endl;}//打印整個XML內容std::string text;rapidxml::print(std::back_inserter(text), doc, 0);std::cout << text << std::endl;// 輸出DOM到文件std::ofstream outfile(XMLFileName.c_str(), std::ios::out); //ofstream默認時,如果文件存在則覆蓋原來的內容,不存在則新建if (outfile){outfile << doc;outfile.close();}doc.clear(); }void main() {const std::string Xmlfilename = "WriteExample.xml";CreateXml(Xmlfilename);std::system("pause");}其結果如下圖所示:
<?xml version='1.0' encoding='utf-8' ?> <!--這是對目標的Annotation保存格式--> <annotation><folder>VOC2007</folder><filename>WriteExample.xml</filename><source><database>My VOC2007 Databas</database><annotation>VOC2007</annotation><image>flickr</image><flickrid>nullptr</flickrid></source><owner><flickrid>nullptr</flickrid><name>aware</name></owner><size><width>1920</width><height>1080</height><depth>3</depth></size><segmented>0</segmented><!--目標的位置狀態信息 --><object><name>example</name><pose>Unspecified</pose><truncated>0</truncated><difficult>0</difficult><bndbox><xmin>11</xmin><ymin>20</ymin><xmax>1000</xmax><ymax>600</ymax></bndbox></object><!--目標的位置狀態信息 --><object><name>example</name><pose>Unspecified</pose><truncated>0</truncated><difficult>0</difficult><bndbox><xmin>11</xmin><ymin>20</ymin><xmax>1000</xmax><ymax>600</ymax></bndbox></object> </annotation>3. 修改及增加刪除
首先是一些對xml的節點解釋:
xml_node類
1)node_type type() const; 獲取結點類型 獲取的類型是枚舉的
2)Ch* name() const; 獲取結點名
3)std::size_t name_size() const; 獲取結點名長度
4)Ch* value() const; 獲取結點值
5)std::size_t value_size() const; 獲取結點值長度
6)xml_node* first_node(const Ch *name = 0, std::size_t name_size = 0, bool case_sensitive = true) const; 獲取DOM Tree第一個子結點的指針
第一個參數為節點名,如果給定第一個參數為”a”, 則該函數尋找結點名為a的第一個子結點;第二個參數為結點名長度
7)xml_node* last_node(const Ch *name = 0, std::size_t name_size = 0, bool case_sensitive = true) const; 獲取DOM Tree最后一個子結點的指針
參數含義同上
8)xml_attribute* first_attribute(const Ch *name = 0, std::size_t name_size = 0, bool case_sensitive = true) const; 獲取結點的第一個屬性指針
9)xml_attribute* next_attribute(const Ch *name = 0, std::size_t name_size = 0, bool case_sensitive = true) const; 獲取結點的下一個屬性指針
10)xml_attribute* last_attribute(const Ch *name = 0, std::size_t name_size = 0, bool case_sensitive = true) const; 獲取結點的最后一個屬性指針
11)xml_node* previous_sibling(const Ch *name = 0, std::size_t name_size = 0, bool case_sensitive = true) const; 獲取上一個同級結點的指針
12)xml_node* next_sibling(const Ch *name = 0, std::size_t name_size = 0, bool case_sensitive = true) const; 獲取下一個同級結點的指針
13)xml_attribute* first_attribute(const Ch *name = 0, std::size_t name_size = 0, bool case_sensitive = true) const; 獲取第一個同級結點的指針
14)xml_attribute* last_attribute(const Ch *name = 0, std::size_t name_size = 0, bool case_sensitive = true) const; 獲取最后一個同級結點的指針
15)void insert_node(xml_node< Ch > *where, xml_node< Ch > *child); 在第一個參數指向的結點之前,插入一個結點
xml_attribute類
1)xml_attribute *previous_attribute(const Ch *name = 0, std::size_t name_size = 0, bool case_sensitive = true) const; 獲取前一個屬性
2)xml_attribute *next_attribute(const Ch *name = 0, std::size_t name_size = 0, bool case_sensitive = true) const;獲取后一個屬性
?
原始數據為:
<config> <SampleFrequency>25</SampleFrequency><SMOKEFireDetection><Detectors><iter><name>fire</name><version>1.3.0</version><confidence>0.5</confidence><bshowDebugWin>1</bshowDebugWin><usefulLabel>3 4 5</usefulLabel><bStandard>1</bStandard></iter><iter><name>smoke</name><version>1.6.0</version><confidence>0.2</confidence><bshowDebugWin>1</bshowDebugWin><usefulLabel>4</usefulLabel><bStandard>1</bStandard></iter><iter><name>motionanalyze</name><version></version><confidence></confidence><bshowDebugWin>1</bshowDebugWin><usefulLabel></usefulLabel></iter></Detectors><ShowReportWin>1</ShowReportWin> </SMOKEFireDetection></config>修改后為:
<config><SMOKEFireDetection><KeyBorad Interface="USB">Logitech</KeyBorad><Detectors><iter><name>fire</name><version>1.3.0</version><confidence>0.5</confidence><bshowDebugWin>1</bshowDebugWin></iter><iter><name>smoke</name><version>1.6.0</version><confidence>0.2</confidence><bshowDebugWin>1</bshowDebugWin><usefulLabel>4</usefulLabel><bStandard>1</bStandard></iter></Detectors></SMOKEFireDetection> </config>感謝?https://www.cnblogs.com/MenAngel/p/11552588.html
總結
以上是生活随笔為你收集整理的rapidxml 文件读写,增加删除节点的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: FTP协议分析实验
- 下一篇: Java中级面试题及答案(120道Jav