RapidXml是指 XML DOM解析工具包,是一個快速的讀寫xml文件的庫文件(hpp)。
(1)創建XML文件
#include <iostream> #include <string> #include <fstream> #include "string.h" #include "rapidxml.hpp" #include "rapidxml_print.hpp" #include "rapidxml_utils.hpp"
static const int buf_len = 2048; static char buf[buf_len] = { 0 }; void createXML(const char * file_name) { // 1.DOM
rapidxml::xml_document<> doc; // 2.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); // 3.node_pi
rapidxml::xml_node<>* dec = doc.allocate_node(rapidxml::node_pi,doc.allocate_string("xml version=\"1.0\" encoding=\"utf-8\"")); doc.append_node(dec); // 4.node_element
rapidxml::xml_node<>* root = doc.allocate_node(rapidxml::node_element, "root"); doc.append_node(root); // 5.node_comment
rapidxml::xml_node<>* comment = doc.allocate_node(rapidxml::node_comment, 0, "這是一個注釋節點"); root->append_node(comment); rapidxml::xml_node<>* students = doc.allocate_node(rapidxml::node_element, "students"); // 6.node_data
rapidxml::xml_node<>* one_student = doc.allocate_node(rapidxml::node_element, "student"); rapidxml::xml_node<>* name = doc.allocate_node(rapidxml::node_data,"node_name","11"); one_student->append_node(name); students->append_node(one_student); // 7.node_element with value
rapidxml::xml_node<>* two_student = doc.allocate_node(rapidxml::node_element, "student","22"); students->append_node(two_student); // 8.set attribute
rapidxml::xml_node<>* three_student = doc.allocate_node(rapidxml::node_element,"student","33"); students->append_node(three_student); three_student->append_attribute(doc.allocate_attribute("course", doc.allocate_string(buf))); three_student->append_attribute(doc.allocate_attribute("score","98")); // 9.node_element without value
rapidxml::xml_node<>* four_student = doc.allocate_node(rapidxml::node_element,"student"); students->append_node(four_student); // 10.node_cdata
rapidxml::xml_node<>* five_student = doc.allocate_node(rapidxml::node_cdata,"student","55"); students->append_node(five_student); // 11.node_cdata
rapidxml::xml_node<>* six_student = doc.allocate_node(rapidxml::node_pi,"student","66"); students->append_node(six_student); // 12.node_cdata
rapidxml::xml_node<>* seven_student = doc.allocate_node(rapidxml::node_doctype,"student","77"); students->append_node(seven_student); root->append_node(students); // 13.輸出DOM到命令行
std::cout<<doc; // 14.輸出DOM到文件
std::ofstream outfile(file_name, std::ios::out); if (outfile) { char *end = rapidxml::print(buf, doc, 0); *end = 0; outfile << buf; outfile.close(); } } int main() { const char *file_name = "rapid.xml"; createXML(file_name); return 0; }
<?xml version="1.0" encoding="utf-8"?>
<?xml version="1.0" encoding="utf-8" ?>
<root>
<!--這是一個注釋節點-->
<students>
<student>11</student>
<student>22</student>
<student course="" score="98">33</student>
<student/>
<![CDATA[55]]>
<?student 66?>
<!DOCTYPE 77>
</students>
</root>
(2)讀取XML文件
//rapidxml_utils.hpp file類 data() 返回 char* 的xml文本內容 size() 返回 unsigned int的文本數據長度
定義:rapidxml::file<0> valName(“filepath”);
//rapidxml.hpp
xml_document類
parse(Ch *text);將文本數據解析為DOM tree
clear();清空DOM tree
定義:rapidxml::xml_document<0> doc;
const int parse_default = 0;
const int parse_full = parse_declaration_node | parse_comment_nodes | parse_doctype_node | parse_pi_nodes | parse_validate_closing_tags
#include <iostream> #include <string> #include <fstream> #include "unistd.h" #include "string.h" #include "rapidxml.hpp" #include "rapidxml_print.hpp" #include "rapidxml_utils.hpp"
static const int buf_len = 2048; static char buf[buf_len] = { 0 }; //利用rapidxml::file讀取配置文件
void readXMLByFile(const char *file_name) { try { // 1.清空緩沖區
memset(buf,0,buf_len); // 2.拼接絕對路徑
std::string strXml = "/home/sunjimeng/test/"; strXml.append(file_name); // 3.用file文件讀入緩沖區
rapidxml::file<> fdoc(strXml.c_str()); // 4.打印從文件中讀取的內容
std::cout<<fdoc.data(); // 5.解析獲取DOM實例
rapidxml::xml_document<> doc; doc.parse<0>(fdoc.data()); }catch(rapidxml::parse_error e) { std::cout<<e.what()<<std::endl; return; } } void readXMLByStream(const char *file_name) { try { // 1.清空緩沖區
memset(buf,0,buf_len); // 2.判斷文件是否存在
if(access(file_name,F_OK) == -1) std::cout<<"xml file "<<file_name<<"is not exits!"<<std::endl; // 3.實例化文件讀取流
std::ifstream infile(file_name, std::ios::in); if(!infile) { std::cout<<"file stream instance error!"<<std::endl; return; } // 4.讀取文件內容到緩沖區
infile.read(buf, buf_len); // 5.輸出文件內容
std::cout<<buf<<std::endl; // 6.實例化DOM
rapidxml::xml_document<> doc; doc.parse<0>(buf); }catch(rapidxml::parse_error e) { std::cout<<e.what()<<std::endl; return; } } int main() { const char *file_name = "rapid.xml"; readXMLByFile(file_name); readXMLByStream(file_name); return 0; }
(3)修改及刪除(接着上文)
//rapidxml.hpp 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;獲取后一個屬性
#include <iostream> #include <string> #include <fstream> #include "unistd.h" #include "string.h" #include "rapidxml.hpp" #include "rapidxml_print.hpp" #include "rapidxml_utils.hpp"
static const int buf_len = 2048; static char buf[buf_len] = { 0 }; void parseXML(const char * file_name) { memset(buf,0,buf_len); try { std::ifstream infile(file_name, std::ios::in); if (!infile) { return; } infile.read(buf, buf_len); std::cout << buf << std::endl; rapidxml::xml_document<> doc; doc.parse<0>(buf); // 取得根節點
rapidxml::xml_node<> *root = doc.first_node("root"); // 遍歷students的子節點
int flag = 0; for (rapidxml::xml_node<> * node = root->first_node("students")->first_node(); node; node = node->next_sibling()) { if(node->first_node() != NULL) std::cout<<"name :"<<node->name()<<" value : "<<node->value()<<std::endl; else std::cout<<"name :"<<node->name()<<" has no value!"<<std::endl; for(rapidxml::xml_attribute<> * attribute = node->first_attribute(); attribute; attribute = attribute->next_attribute()) std::cout<<" attribute name = "<<attribute->name()<<" attribute value = "<<attribute->value()<<std::endl; } } catch(rapidxml::parse_error e) { std::cout<<e.what()<<std::endl; } } void modifyXML(const char * file_name) { memset(buf,0,buf_len); //用file解析DOM時必須是絕對路徑
std::string strXml = "/home/sunjimeng/test/"; strXml.append(file_name); rapidxml::file<> fdoc(strXml.c_str()); //打印讀取的文件 //std::cout<<fdoc.data();
rapidxml::xml_document<> doc; doc.parse<0>(fdoc.data()); //取得根節點
rapidxml::xml_node<> *root = doc.first_node("root"); rapidxml::xml_node<> *students = root->first_node("students"); if(students != NULL) std::cout<<"student is not null"<<std::endl; else
return; //刪除最后一個元素
if(students->last_node() != NULL) students->remove_last_node(); //刪除第一個元素
if(students->first_node() != NULL) students->remove_first_node(); rapidxml::xml_node<> *ptrNode = students->first_node(); int size = 0; while(ptrNode) { size++; //刪除所有屬性
ptrNode->remove_all_attributes(); ptrNode = ptrNode->next_sibling(); } std::cout<<"size = "<<size<<std::endl; std::string text; rapidxml::print(std::back_inserter(text),doc,0); std::cout<<text<<std::endl; std::ofstream out(file_name); out<<doc; } int main() { const char *file_name = "rapid.xml"; modifyXML(file_name); parseXML(file_name); return 0; }
student is not null size = 1
<root>
<students>
<student>33</student>
</students>
</root>
<root>
<students>
<student>33</student>
</students>
</root> name :student value : 33