日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程语言 > asp.net >内容正文

asp.net

RapidXml读取并修改XML文件

發布時間:2024/8/1 asp.net 33 豆豆
生活随笔 收集整理的這篇文章主要介紹了 RapidXml读取并修改XML文件 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

RapidXml讀取并修改XML文件

  • RapidXml介紹
  • RapidXml讀取與修改xml文件

RapidXml介紹

?????RapidXml嘗試創建最快的XML解析器,同時保留可用性,可移植性和合理的W3C兼容性。它是一個用現代C ++編寫的原位解析器,解析速度接近strlen在同一數據上執行的函數。它僅僅只由四個頭文件組成,并不要單獨進行配置編譯,使用起來非常方便。
在RapidXml的官網上,它發布了與其他xml解析庫的速度對比,應該可以說RapidXml是目前最快的xml解析器。

RapidXml通過使用以下幾種技術實現了它的速度:
1,原位解析。構建DOM樹時,RapidXml不會復制字符串數據,例如節點名稱和值。相反,它存儲指向源文本內部的指針。
2,使用模板元編程技術。這允許它將大部分工作轉移到編譯時。通過模板的魔力,C ++編譯器為您使用的任何解析器標志組合生成解析代碼的單獨副本。在每個副本中,所有可能的決定都在編譯時進行,并且省略所有未使用的代碼。
3,廣泛使用查找表進行解析。
4,手動調優的C ++,在幾個最流行的CPU上進行了分析。

RapidXml讀取與修改xml文件

?????我們以下面這個xml為例,找到key值為"ReportIndex"的節點,并在這個節點前面插入一個新的節點"",同時將key值為"ReportIndex"的節點以及后面的節點的offset值都加上4。

<hsbinmsg limit_size="5096" note="hsbinmsg msgtype info"><head note="packet head"><field key="msgtype" type="6" offset="0"/><field key="bodylength" type="6" offset="4"/></head><tail note="packet tail"><field key="checksum" type="6" offset="-1"/></tail><msgtype id="202098" name="DesignationReport(202098)"><dataset note=""><field key="ReportIndex" type="7" offset="12" size="8"/><field key="app1id" type="17" offset="20" size="3"/></dataset></msgtype> </hsbinmsg>

?????CXmlParse解析類的頭文件如下:

#pragma once #include "rapidxml.hpp" #include "rapidxml_utils.hpp" #include "rapidxml_print.hpp" #include <string>#define XML_NODE_NAME "msgtype" #define XML_NODE_NAME2 "ReportIndex"#define OFFSET_SIZE 4class CXmlParse { public:CXmlParse(const std::string &strPath);~CXmlParse();private:int LoadXml();//找到key為name的屬性bool GetAttrByName(const char* name, rapidxml::xml_node<>* pNode, rapidxml::xml_attribute<> *&pAttr);void UpdateAtributeValue(rapidxml::xml_document<> &doc, rapidxml::xml_attribute<>* &pAttr, int nOffset);void MakeFileCopy(const std::string& strPath);private:std::string m_strPath;std::string m_strNewPath; };

?????cpp實現文件:

#include "XmlParse.h" #include <windows.h> #include <iostream>CXmlParse::CXmlParse(const std::string &strPath) {m_strPath = strPath;MakeFileCopy(m_strPath);if (LoadXml()){std::cout << "XML處理成功" << std::endl;}else{std::cout << "XML處理失敗" << std::endl;} }CXmlParse::~CXmlParse() {}//加載xml int CXmlParse::LoadXml() {if (m_strPath.empty()){return -1;}try{rapidxml::file<> file(m_strPath.c_str());rapidxml::xml_document<> doc;doc.parse<0>(file.data());//根節點rapidxml::xml_node<>* root = doc.first_node();rapidxml::xml_node<>* pNode = root->first_node();while (pNode) //第二層節點head,msgtype{std::string strName = pNode->name();if (strName.compare(XML_NODE_NAME) == 0) //找到msgtype{rapidxml::xml_node<>* pNode2 = pNode->first_node(); //第三層節點datasetif (pNode2){rapidxml::xml_node<>* pNode3 = pNode2->first_node(); //第四層節點field,只找第一個bool bFind = false;rapidxml::xml_attribute<> *attr;if (GetAttrByName("key", pNode3, attr)){if (strcmp(attr->value(), "ReportIndex") == 0){bFind = true;}}if (bFind){//遍歷第四層節點field節點, offset偏移量+4while (pNode3){rapidxml::xml_attribute<> *attrSize;GetAttrByName("offset", pNode3, attrSize);UpdateAtributeValue(doc, attrSize, OFFSET_SIZE);pNode3 = pNode3->next_sibling();}//只要找到了一個key="ReportIndex"的field,那么就需要新插入一個noderapidxml::xml_node<> *pNewNode = doc.allocate_node(rapidxml::node_element, "field");if (pNewNode){pNewNode->append_attribute(doc.allocate_attribute("key", "PartitionNo"));pNewNode->append_attribute(doc.allocate_attribute("type", "6"));pNewNode->append_attribute(doc.allocate_attribute("offset", "8"));pNewNode->append_attribute(doc.allocate_attribute("size", "4"));pNode2->prepend_node(pNewNode);}}}}pNode = pNode->next_sibling();}std::ofstream out(m_strNewPath);out << doc;out.close(); return 1;}catch (...){std::cout << "XML解析出現異常" << std::endl;return -1;} }//獲取到節點中key為name的屬性 bool CXmlParse::GetAttrByName(const char* name, rapidxml::xml_node<>* pNode, rapidxml::xml_attribute<> *&pAttr) {if (pNode == NULL)return false;for (rapidxml::xml_attribute<> *attr = pNode->first_attribute(); attr; attr = attr->next_attribute()){if (strcmp(attr->name(), name) == 0){pAttr = attr;return true;}}return true; }//更新屬性的值 void CXmlParse::UpdateAtributeValue(rapidxml::xml_document<> &doc, rapidxml::xml_attribute<>* &pAttr, int nOffset) {if (NULL == pAttr)return;const char* oldValue = pAttr->value();int nValue = atoi(oldValue);nValue += nOffset;char str[12];memset(str, 0, 12);_itoa_s(nValue, str, 10);pAttr->value(doc.allocate_string(str), strlen(str)); }//根據原路徑得到新路徑(原路徑名+“2”) void CXmlParse::MakeFileCopy(const std::string& strPath) {std::string strNewPath = strPath;int nPos = strNewPath.find_last_of(".");if (nPos != std::string::npos){std::string strTemp = strNewPath.substr(nPos + 1);strNewPath = strNewPath.substr(0, nPos);strNewPath += "2.";strNewPath += strTemp;m_strNewPath = strNewPath;} }

?????RapidXml遍歷節點跟TinyXml遍歷節點的方式一樣,都是先獲取根節點,然后獲取到根節點下方的first_node(),然后通過next_sibling()不停地指向下一個兄弟節點,同時兄弟節點也可以深度去遍歷。獲取節點的各個屬性值也是一樣的使用方式。
?????本程序為了和原xml文件作對比,就創建了新的文件,如果想在原文件上做修改,直接將std::ofstream out(m_strNewPath);中的m_strNewPath替換為m_strPath即可。
類封裝好后,調用也非常方便。

CXmlParse parse(strPath);

?????附上完整例子代碼:Demo

總結

以上是生活随笔為你收集整理的RapidXml读取并修改XML文件的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。