当前位置: 首页> 房产> 建筑 > pugixml编写一个xml工具类并且满足事务以及数据一致性

pugixml编写一个xml工具类并且满足事务以及数据一致性

时间:2025/7/13 5:42:48来源:https://blog.csdn.net/sinat_27674731/article/details/141135393 浏览次数:0次

使用pugixml编写一个xml工具类满足以下要求:1.可以依据xpath对xml进行增删改查。2.操作时必须保证数据的一致性。3.满足事务

#include <iostream>
#include <string>
#include <vector>
#include "pugixml.hpp"class XmlTool {
public:explicit XmlTool(const std::string& xmlContent) {try {if (!doc.load_string(xmlContent.c_str())) {throw std::runtime_error("Failed to load XML content.");}originalDoc.reset(doc); // 保存原始文档副本} catch (const std::bad_alloc& e) {throw std::runtime_error(std::string("Memory allocation failed: ") + e.what());}}void add(const std::string& xpath, const std::string& newNode) {try {pugi::xpath_node node = doc.select_node(xpath.c_str());if (!node) {throw std::runtime_error("XPath not found.");}pugi::xml_node parentNode = node.node();pugi::xml_document tempDoc;tempDoc.load_string(newNode.c_str());parentNode.append_copy(tempDoc.first_child());} catch (const std::bad_alloc& e) {throw std::runtime_error(std::string("Memory allocation failed during add: ") + e.what());} catch (const std::exception& e) {throw;}}void remove(const std::string& xpath) {try {pugi::xpath_node node = doc.select_node(xpath.c_str());if (!node) {throw std::runtime_error("XPath not found.");}pugi::xml_node targetNode = node.node();targetNode.parent().remove_child(targetNode);} catch (const std::exception& e) {throw;}}void modify(const std::string& xpath, const std::string& newValue) {try {pugi::xpath_node node = doc.select_node(xpath.c_str());if (!node) {throw std::runtime_error("XPath not found.");}// 分段处理属性值const size_t chunkSize = 1000; // 每次处理的字符数,可以根据需要调整pugi::xml_node xmlNode = node.node();xmlNode.text().set(""); // 清空原有内容for (size_t i = 0; i < newValue.size(); i += chunkSize) {std::string chunk = newValue.substr(i, chunkSize);xmlNode.text().append_buffer(chunk.c_str(), chunk.size());}} catch (const std::bad_alloc& e) {throw std::runtime_error(std::string("Memory allocation failed during modify: ") + e.what());} catch (const std::exception& e) {throw;}}void commit() {try {originalDoc.reset(doc);} catch (const std::exception& e) {throw std::runtime_error(std::string("Failed to commit changes: ") + e.what());}}void rollback() {try {doc.reset(originalDoc);} catch (const std::exception& e) {throw std::runtime_error(std::string("Failed to rollback changes: ") + e.what());}}std::string getXml() const {try {std::ostringstream oss;doc.save(oss);return oss.str();} catch (const std::exception& e) {throw std::runtime_error(std::string("Failed to retrieve XML content: ") + e.what());}}private:pugi::xml_document doc;pugi::xml_document originalDoc;
};class XmlManager {
public:void addXmlDocument(const std::string& xmlContent) {try {xmlTools.emplace_back(xmlContent);} catch (const std::exception& e) {throw std::runtime_error(std::string("Failed to add XML document: ") + e.what());}}void add(const std::string& xpath, const std::string& newNode, size_t docIndex) {try {if (docIndex >= xmlTools.size()) {throw std::out_of_range("Document index out of range.");}xmlTools[docIndex].add(xpath, newNode);} catch (const std::exception& e) {throw std::runtime_error(std::string("Failed to add node: ") + e.what());}}void remove(const std::string& xpath, size_t docIndex) {try {if (docIndex >= xmlTools.size()) {throw std::out_of_range("Document index out of range.");}xmlTools[docIndex].remove(xpath);} catch (const std::exception& e) {throw std::runtime_error(std::string("Failed to remove node: ") + e.what());}}void modify(const std::string& xpath, const std::string& newValue, size_t docIndex) {try {if (docIndex >= xmlTools.size()) {throw std::out_of_range("Document index out of range.");}xmlTools[docIndex].modify(xpath, newValue);} catch (const std::exception& e) {throw std::runtime_error(std::string("Failed to modify node: ") + e.what());}}void commitAll() {try {for (auto& xmlTool : xmlTools) {xmlTool.commit();}} catch (const std::exception& e) {throw std::runtime_error(std::string("Failed to commit changes: ") + e.what());}}void rollbackAll() {try {for (auto& xmlTool : xmlTools) {xmlTool.rollback();}} catch (const std::exception& e) {throw std::runtime_error(std::string("Failed to rollback changes: ") + e.what());}}void printAllXml() const {try {for (size_t i = 0; i < xmlTools.size(); ++i) {std::cout << "XML Document " << i + 1 << ":\n" << xmlTools[i].getXml() << std::endl;}} catch (const std::exception& e) {throw std::runtime_error(std::string("Failed to print XML documents: ") + e.what());}}private:std::vector<XmlTool> xmlTools;
};int main() {std::string xmlContent1 = R"(<root><item id="1">First</item><item id="2">Second</item></root>)";std::string xmlContent2 = R"(<data><entry id="a">Alpha</entry><entry id="b">Beta</entry></data>)";XmlManager xmlManager;try {xmlManager.addXmlDocument(xmlContent1);xmlManager.addXmlDocument(xmlContent2);std::cout << "Original XMLs:\n";xmlManager.printAllXml();xmlManager.add("/root/item[@id='1']", R"(<item id="3">Third</item>)", 0);// 处理一个非常大的属性值xmlManager.modify("/root/item[@id='2']", std::string(1000001, 'X'), 0);xmlManager.add("/data/entry[@id='a']", R"(<entry id="c">Gamma</entry>)", 1);xmlManager.modify("/data/entry[@id='b']", "Updated Beta", 1);xmlManager.commitAll();std::cout << "\nCommitted XMLs:\n";xmlManager.printAllXml();} catch (const std::exception& e) {std::cerr << "Exception: " << e.what() << "\nRolling back all changes..." << std::endl;xmlManager.rollbackAll();std::cout << "\nRolled back XMLs:\n";xmlManager.printAllXml();}return 0;
}
关键字:pugixml编写一个xml工具类并且满足事务以及数据一致性

版权声明:

本网仅为发布的内容提供存储空间,不对发表、转载的内容提供任何形式的保证。凡本网注明“来源:XXX网络”的作品,均转载自其它媒体,著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处。

我们尊重并感谢每一位作者,均已注明文章来源和作者。如因作品内容、版权或其它问题,请及时与我们联系,联系邮箱:809451989@qq.com,投稿邮箱:809451989@qq.com

责任编辑: