#include "xml_opr.h" CXmlOpr::CXmlOpr() = default; CXmlOpr::~CXmlOpr() = default; bool CXmlOpr::open(const std::string& xml_path) { if (doc_.LoadFile(xml_path.c_str()) != tinyxml2::XML_SUCCESS) { return false; } xml_path_ = xml_path; return true; } void CXmlOpr::set_baseinfo(const OprBase& base) { opr_base_ = base; } bool CXmlOpr::parse_xml(std::vector& vec) { std::string next_node{}; std::string node_path = opr_base_.node_path; keys_.clear(); auto keys = splitString(opr_base_.purpose, ","); for (const auto& item : keys) { if (item.empty()) { continue; } keys_.push_back(item); } auto nodes = splitString(opr_base_.node_path, "/"); for (const auto& item : nodes) { if (item.empty()) { continue; } if (parent_node_ == nullptr) { parent_node_ = doc_.FirstChildElement(item.c_str()); } else { parent_node_ = parent_node_->FirstChildElement(item.c_str()); } } vec.clear(); Element_t* purpose_node = parent_node_->FirstChildElement(opr_base_.the_node.c_str()); while (purpose_node) { vec.push_back(purpose_node); purpose_node = purpose_node->NextSiblingElement(); } return true; } // 排序后(仅指针排序)的节点进行复制(让实际内容有序),删除原始节点 void CXmlOpr::copy_and_del(std::vector& vec, std::vector& out) { out.clear(); // 先找到最后一个节点 Element_t* last_node = parent_node_->LastChildElement(opr_base_.the_node.c_str()); Element_t* last_node_bk = last_node; if (last_node == nullptr) { return; } for (const auto& data : vec) { Element_t* n = copy_element(data); out.push_back(n); insert_brother_node(last_node, n); last_node = n; } // 删除原有的节点 Element_t* fnode = parent_node_->FirstChildElement(opr_base_.the_node.c_str()); Element_t* fnext = fnode->NextSiblingElement(); while (fnode != last_node_bk) { parent_node_->DeleteChild(fnode); fnode = fnext; fnext = fnode->NextSiblingElement(); } parent_node_->DeleteChild(last_node_bk); } void CXmlOpr::insert_brother_node(Element_t* brother, Element_t* newer) { if (!brother || !newer) { return; } parent_node_->InsertAfterChild(brother, newer); } Element_t* CXmlOpr::copy_element(Element_t* ele) { if (!ele) { return nullptr; } Element_t* ret = doc_.NewElement(ele->Name()); const auto* attribute = ele->FirstAttribute(); while (attribute) { ret->SetAttribute(attribute->Name(), attribute->Value()); attribute = attribute->Next(); } return ret; } void CXmlOpr::del_element(Element_t* ele) { parent_node_->DeleteChild(ele); } bool CXmlOpr::check_key_exists(const Property_t& property) { if (keys_.size() < 1 || property.size() < 1) { return false; } Element_t* purpose_node = parent_node_->FirstChildElement(opr_base_.the_node.c_str()); while (purpose_node) { const char* value = purpose_node->Attribute(keys_[0].c_str()); if (property[0].value == std::string(value)) { return true; } purpose_node = purpose_node->NextSiblingElement(); } return false; } bool CXmlOpr::save() { auto ret = doc_.SaveFile(xml_path_.c_str()); if (ret != tinyxml2::XML_SUCCESS) { return false; } return true; } void CXmlOpr::get_key_value(Element_t* ele, Property_t& vec) { if (ele == nullptr) { return; } vec.clear(); const auto* attribute = ele->FirstAttribute(); while (attribute) { vec.emplace_back(attribute->Name(), attribute->Value()); attribute = attribute->Next(); } } void CXmlOpr::key_value_to_element(Element_t* ele, const Property_t& vec) { if (ele == nullptr) { return; } for (const auto& data : vec) { ele->SetAttribute(data.key.c_str(), data.value.c_str()); } } SKeyValue::SKeyValue(const char* pkey, const char* pvalue) { key = std::string(pkey); value = std::string(pvalue); }