TinyXML用法小结
来源:互联网 发布:foxit editor mac 编辑:程序博客网 时间:2024/06/14 02:03
TinyXML用法小结
TinyXML用法小结
1. 介绍
Tinyxml的官方网址:http://www.grinninglizard.com
官方介绍文档:http://www.grinninglizard.com/tinyxmldocs/tutorial0.html
在TinyXML中,根据XML的各种元素来定义了一些类:
TiXmlBase:整个TinyXML模型的基类。
TiXmlAttribute:对应于XML中的元素的属性。
TiXmlNode:对应于DOM结构中的节点。
TiXmlComment:对应于XML中的注释
TiXmlDeclaration:对应于XML中的申明部分,即<?versiong="1.0" ?>。
TiXmlDocument:对应于XML的整个文档。
TiXmlElement:对应于XML的元素。
TiXmlText:对应于XML的文字部分
TiXmlUnknown:对应于XML的未知部分。
TiXmlHandler:定义了针对XML的一些操作。
根据下图来说明常用的类对应的文本格式:
<?xml version="1.0" ?> //TiXmlDeclaration,声明<MyApp> //TiXmlElement,元素 <!-- Settings for MyApp -->//TiXmlComment,注释 <Messages>//TiXmlElement,元素 <Welcome>Welcome to MyApp</Welcome>//<Welcome>是元素TiXmlElement ,“Welcome to MyApp”是TiXmlText,文本 <Farewell>Thank you for using MyApp</Farewell>//同上 </Messages> <Windows>//TiXmlElement,元素 <Window name="MainFrame" x="5" y="15" w="400" h="250" />// Window是元素TiXmlElement ,name、x、y、h是TiXmlAttribute </Windows> <Connection ip="192.168.0.1" timeout="123.456000" /></MyApp>
TinyXML是个解析库,主要由DOM模型类(TiXmlBase、TiXmlNode、TiXmlAttribute、TiXmlComment、TiXmlDeclaration、TiXmlElement、TiXmlText、TiXmlUnknown)和操作类(TiXmlHandler)构成。它由两个头文件(.h文件)和四个CPP文件(.cpp文件)构成,用的时候,只要将(tinyxml.h、tinystr.h、tinystr.cpp、tinyxml.cpp、tinyxmlerror.cpp、tinyxmlparser.cpp)导入工程就可以用它的东西了。如果需要,可以将它做成自己的DLL来调用。
注意,TiXmlBase 是TiXmlNode的基类,TiXmlNode是TiXmlElement、TiXmlComment、TiXmlText、TiXmlDeclaration、TiXmlUnknown、TiXmlDocument的基类。
2. TinyXML配置
在stdafx.h头文件中增加头文件引用#include "tinyxml/tinyxml.h"
在工程设置中加入lib引用库
在stdafx.h中加入动态库引用
#ifdef _DEBUG#pragma comment(lib,"TinyXMLD.lib")#else#pragma comment(lib,"TinyXML.lib")#endif
3. TinyXML读取和保存文件
3.1 读取xml文件
TiXmlDocument lconfigXML;if( !lconfigXML.LoadFile( strXmlFile.c_str() ) ){ break;}
3.2 读取xml参数
TiXmlDocument lActionXML;lActionXML.Parse(strRmcpParam.c_str());if(lActionXML.Error()){ strErr = "输入参数不是标准的xml格式"; return false; }
3.3 保存xml参数到文本
TiXmlDocument tyDoc;…tyDoc.SaveFile(m_strFilePath);
3.4 保存xml参数到临时变量
TiXmlDocument tyDoc;…TiXmlPrinter printer;tyDoc.Accept(&printer);std::string devParam = std::string(printer.CStr());
4. TinyXML增删改查
4.1 增
创建一个如1中的xml文件代码
void write_app_settings_doc( ) { TiXmlDocument doc; TiXmlElement* msg; TiXmlDeclaration* decl = new TiXmlDeclaration( "1.0", "", "" ); doc.LinkEndChild( decl ); TiXmlElement * root = new TiXmlElement( "MyApp" ); doc.LinkEndChild( root ); TiXmlComment * comment = new TiXmlComment(); comment->SetValue(" Settings for MyApp " ); root->LinkEndChild( comment ); TiXmlElement * msgs = new TiXmlElement( "Messages" ); root->LinkEndChild( msgs ); msg = new TiXmlElement( "Welcome" ); msg->LinkEndChild( new TiXmlText( "Welcome to MyApp" )); msgs->LinkEndChild( msg ); msg = new TiXmlElement( "Farewell" ); msg->LinkEndChild( new TiXmlText( "Thank you for using MyApp" )); msgs->LinkEndChild( msg ); TiXmlElement * windows = new TiXmlElement( "Windows" ); root->LinkEndChild( windows ); TiXmlElement * window; window = new TiXmlElement( "Window" ); windows->LinkEndChild( window ); window->SetAttribute("name", "MainFrame"); window->SetAttribute("x", 5); window->SetAttribute("y", 15); window->SetAttribute("w", 400); window->SetAttribute("h", 250); TiXmlElement * cxn = new TiXmlElement( "Connection" ); root->LinkEndChild( cxn ); cxn->SetAttribute("ip", "192.168.0.1"); cxn->SetDoubleAttribute("timeout", 123.456); // floating point attrib dump_to_stdout( &doc ); doc.SaveFile( "appsettings.xml" ); }
在节点最后插入新节点
TiXmlNode* LinkEndChild( TiXmlNode* addThis );
在节点后 前/后 插入新节点
TiXmlNode* InsertBeforeChild( TiXmlNode* beforeThis, const TiXmlNode& addThis );TiXmlNode* InsertAfterChild( TiXmlNode* afterThis, const TiXmlNode& addThis );
4.2 删
删除某个节点, TiXmlNode是TiXmlElement、TiXmlComment、TiXmlText、TiXmlDeclaration、TiXmlUnknown、TiXmlDocument的基类
TiXmlNode node;node.Clear();
从A节点上移除子节点B
TiXmlNode nodeA;nodeA. RemoveChild( TiXmlNode* removeThis );
从元素A上移除名字为B的属性
TiXmlAttribute attrA;attrA. RemoveAttribute( const char * name );
4.3 改
查找内容为<mfid val="1234" />,现需要将1234改成其他值
TiXmlNode* lpnode = NULL;lpnode = tixml.RootElement()->IterateChildren("mfid",lpnode);TiXmlAttribute* tiattr = lpnode->ToElement()->FirstAttribute();//找到mfid节点,获取第一个属性值。注意,如果有多个属性值,需要判断哪个属性值是需要的tiattr->SetValue(mfid.c_str());
替换一个节点
TiXmlNode* ReplaceChild( TiXmlNode* replaceThis, const TiXmlNode& withThis );
4.4 查
获取link节点
const TiXmlNode* lpItemNode = NULL;//初始化lpItemNode = lconfigXML.RootElement()->IterateChildren("link", lpItemNode);if (lpItemNode == NULL){ //Can not find <link>break;}
获取link节点中的type属性值
std::string strType = lpItemNode->ToElement()->Attribute("type");
遍历节点
const TiXmlNode* lpMapNode = NULL; //初始化lpMapNode = lconfigXML.RootElement()->IterateChildren("node", lpMapNode);if (lpMapNode) { rms::CStationMapping litem; const TiXmlNode* lpItemNode = NULL ; while(lpItemNode = lpMapNode->IterateChildren("item",lpItemNode)) { string str = lpItemNode->ToElement()->Attribute("ABC"); }}
遍历元素属性
TiXmlAttribute* pAttr = NULL; for (pAttr = pNode->FirstAttribute(); pAttr; pAttr = pAttr->Next()) { …}
节点的下一个兄弟节点
const TiXmlNode* NextSibling() const;
元素的下一个元素
const TiXmlElement* NextSiblingElement() const;
属性的下一个属性
const TiXmlAttribute* Next() const;
返回值为NULL表示不存在
5. TinyXml常用操作封装
使用TinyXml的时候,经常会遇到两个问题:
1:TinyXml不检查输入参数,如果参数输入不当,会偶发异常。且该异常不易捕捉。
2:处理较大规模xml的时候,类似IterateChildren等的语句会出现很多行,重复代码量很大。 为解决以上两个问题,我对TinyXml进行简单封装。对于问题1,定义了几种处理状态,当参数不当或其他问题发生时,会返回对应的错误代码。用GetStatus可解析出该异常。
1 //tinyxml 宏 2 //N:Node,C:Child node,Cn:Child node's name,An:Attribute name,V:Value(string类型) 3 //D:tixmldocument,P:tixmlprinter,p:param,Pre:previous 4 #ifndef TNXML_COMMON 5 #define TNXML_COMMON 6 7 #define TNXML_XML_PARAM -2 8 #define TNXML_XML_FILE -1 9 10 #define TNXML_OK 0 11 #define TNXML_NOT_FIND_NODE 1 12 #define TNXML_NOT_FIND_ATTR 2 13 #define TNXML_PARAM_NODE_NULL 3 14 #define TNXML_PARAM_STR_NULL 4 15 #define TNXML_PARAM_NOT_XML 5 16 #define TNXML_OTHER_ERROR 9 17 18 class CTNXML 19 { 20 public: 21 //查找节点N下子节点Cn(Pre节点后),用output返回 22 static int CN(TiXmlNode* N,std::string Cn,TiXmlNode* Pre,TiXmlNode*& output) 23 { 24 if (N == NULL) 25 { 26 return TNXML_PARAM_NODE_NULL; 27 } 28 if (Cn.empty()) 29 { 30 return TNXML_PARAM_STR_NULL; 31 } 32 TiXmlNode* node = N->IterateChildren(Cn.c_str(),Pre); 33 if (node) 34 { 35 output = node; 36 return TNXML_OK; 37 } 38 else 39 { 40 41 return TNXML_NOT_FIND_NODE; 42 } 43 } 44 45 //查找节点N下属性An的值,用output返回 46 static int ELE_ATTR_VAL(TiXmlNode* N,std::string An,std::string& output) 47 { 48 if (N == NULL) 49 { 50 return TNXML_PARAM_NODE_NULL; 51 } 52 else if (An.empty()) 53 { 54 return TNXML_PARAM_STR_NULL; 55 } 56 if (N->ToElement()->Attribute(An.c_str()) == NULL) 57 { 58 return TNXML_NOT_FIND_ATTR; 59 } 60 else 61 { 62 output = N->ToElement()->Attribute(An.c_str()); 63 return TNXML_OK; 64 } 65 } 66 67 //查找节点N下子节点Cn(Pre节点后),用output返回Cn下属性An的值 68 static int ITER_ELE_ATTR_VAL(TiXmlNode* N,std::string Cn,TiXmlNode* Pre,std::string An,std::string& output) 69 { 70 TiXmlNode* node = NULL; 71 int res = CN(N,Cn,Pre,node); 72 if ( res == TNXML_OK) 73 { 74 std::string str; 75 res = ELE_ATTR_VAL(node,An,str); 76 if (res == TNXML_OK) 77 { 78 output = str; 79 return TNXML_OK; 80 } 81 else 82 { 83 return res; 84 } 85 } 86 else 87 { 88 return res; 89 } 90 } 91 92 //设置节点N下属性An的值为V 93 static int ELE_SET_ATTR(TiXmlNode* N,std::string An,std::string V) 94 { 95 if (N == NULL) 96 { 97 return TNXML_PARAM_NODE_NULL; 98 } 99 else if (An.empty())100 {101 return TNXML_PARAM_STR_NULL;102 }103 else104 {105 N->ToElement()->SetAttribute(An.c_str(),V.c_str());106 return TNXML_OK;107 }108 }109 110 //设置节点N下子节点Cn(Pre后)属性An的值为V111 static int ITER_ELE_SET_ATTR_VAL(TiXmlNode* N,std::string Cn,TiXmlNode* Pre,std::string An,std::string V)112 {113 TiXmlNode* node = NULL;114 int res = CN(N,Cn,Pre,node);115 if ( res == TNXML_OK)116 {117 res = ELE_SET_ATTR(node,An,V);118 return res;119 }120 else121 {122 return res;123 }124 }125 126 //读取xml参数(字符串),返回根节点127 static int PARAM_TO_ROOTELE(std::string& str,TiXmlElement* output)128 {129 if (str.empty())130 {131 return TNXML_PARAM_STR_NULL;132 }133 TiXmlDocument* D = new TiXmlDocument;134 if (D->Parse(str.c_str()))135 {136 output = D->RootElement();137 if (output)138 {139 return TNXML_OK;140 }141 else142 {143 return TNXML_PARAM_NOT_XML;144 }145 }146 else147 {148 return TNXML_PARAM_NOT_XML;149 }150 }151 152 //读取xml参数(文件地址),返回根节点153 static int DOC_TO_ROOTELE(std::string& str,TiXmlElement* output)154 {155 if (str.empty())156 {157 return TNXML_PARAM_STR_NULL;158 }159 TiXmlDocument* D = new TiXmlDocument;160 if (D->LoadFile(str.c_str()))161 {162 output = D->RootElement();163 if (output)164 {165 return TNXML_OK;166 }167 else168 {169 return TNXML_PARAM_NOT_XML;170 }171 }172 else173 {174 return TNXML_PARAM_NOT_XML;175 }176 }177 178 //N尾部插入名为Cn的新节点,属性名值An,值V179 static int LinkNewNodeWithAttr(TiXmlNode* N,std::string Cn,std::string An,std::string V,TiXmlElement*& C)180 {181 if (N == NULL)182 {183 return TNXML_PARAM_NODE_NULL;184 }185 if (Cn.empty() || An.empty())186 {187 return TNXML_PARAM_STR_NULL;188 }189 TiXmlElement* ele = new TiXmlElement(Cn);190 ele->SetAttribute(An,V);191 N->LinkEndChild(ele);192 193 C = ele;194 return TNXML_OK;195 }196 197 //保存TiXmlDocument文档为字符串198 static int Doc_To_String(TiXmlDocument& D,std::string& output)199 {200 TiXmlPrinter t_printer; 201 if (D.Accept(&t_printer))202 {203 output = std::string(t_printer.CStr());204 return TNXML_OK;205 }206 else207 {208 return TNXML_OTHER_ERROR;209 }210 };211 212 //保存TiXmlElement文档为字符串213 static int Ele_To_String(TiXmlElement* N,std::string& output)214 {215 if (N==NULL)216 {217 return TNXML_PARAM_NODE_NULL;218 }219 TiXmlNode* ele = N->Clone();220 if (ele)221 {222 TiXmlDocument doc;223 doc.LinkEndChild(ele);224 return Doc_To_String(doc,output);225 }226 else227 {228 return TNXML_OTHER_ERROR;229 }230 };231 232 //保存ele至本地文件233 static int Ele_To_File(TiXmlElement* N,std::string filepath)234 {235 if (N==NULL)236 {237 return TNXML_PARAM_NODE_NULL;238 }239 TiXmlNode* ele = N->Clone();240 TiXmlDocument doc;241 doc.LinkEndChild(ele);242 doc.SaveFile(filepath.c_str());243 return TNXML_OK;244 };245 246 247 //将字符串转成小写248 static void Xml_To_Lower(std::string& param)249 {250 std::transform(param.begin(), param.end(), param.begin(), std::tolower);251 }252 253 //解析以上函数反馈信息254 static std::string GetStatus(int index)255 {256 switch (index)257 {258 case TNXML_OK:259 {260 return std::string("OK");261 }262 case TNXML_NOT_FIND_NODE:263 {264 return std::string("Cannot find node");265 }266 break;267 case TNXML_NOT_FIND_ATTR:268 {269 return std::string("Cannot find attribute");270 }271 break;272 case TNXML_PARAM_NODE_NULL:273 {274 return std::string("Input param node is NULL");275 }276 break;277 case TNXML_PARAM_STR_NULL:278 {279 return std::string("Input param string is NULL");280 }281 break;282 case TNXML_PARAM_NOT_XML:283 {284 return std::string("Input param string is not XML");285 }286 break;287 case TNXML_OTHER_ERROR:288 {289 return std::string("Other errors");290 }291 break;292 default:293 {294 return std::string("Unknown");295 }296 break;297 }298 }299 };300 301 #endif
以上是我目前经常用到的处理语句,以后会逐步扩展其他操作语句。
6. 一个完整例子
void AppSettings::load(const char* pFilename){ TiXmlDocument doc(pFilename); if (!doc.LoadFile()) return; TiXmlHandle hDoc(&doc); TiXmlElement* pElem; TiXmlHandle hRoot(0); // block: name { pElem=hDoc.FirstChildElement().Element(); // should always have a valid root but handle gracefully if it does if (!pElem) return; m_name=pElem->Value(); // save this for later hRoot=TiXmlHandle(pElem); } // block: string table { m_messages.clear(); // trash existing table pElem=hRoot.FirstChild( "Messages" ).FirstChild().Element(); for( pElem; pElem; pElem=pElem->NextSiblingElement()) { const char *pKey=pElem->Value(); const char *pText=pElem->GetText(); if (pKey && pText) { m_messages[pKey]=pText; } } } // block: windows { m_windows.clear(); // trash existing list TiXmlElement* pWindowNode=hRoot.FirstChild( "Windows" ).FirstChild().Element(); for( pWindowNode; pWindowNode; pWindowNode=pWindowNode->NextSiblingElement()) { WindowSettings w; const char *pName=pWindowNode->Attribute("name"); if (pName) w.name=pName; pWindowNode->QueryIntAttribute("x", &w.x); // If this fails, original value is left as-is pWindowNode->QueryIntAttribute("y", &w.y); pWindowNode->QueryIntAttribute("w", &w.w); pWindowNode->QueryIntAttribute("hh", &w.h); m_windows.push_back(w); } } // block: connection { pElem=hRoot.FirstChild("Connection").Element(); if (pElem) { m_connection.ip=pElem->Attribute("ip"); pElem->QueryDoubleAttribute("timeout",&m_connection.timeout); } }}
»下一篇:gSoap工具wsdl2h及soapcpp2指令汇总
posted on 2016-09-02 15:21 炽离 阅读(4534) 评论(0)编辑 收藏
- TinyXML用法小结
- TinyXml小结
- TinyXML应用小结
- tinyXML中FirstChild用法
- tinyxml用法学习
- TinyXml的基本用法
- TinyXML的简单用法
- TinyXML 用法:读/写配置文件
- tinyxml的用法和实例
- MFC中TinyXml的用法
- Windows Tinyxml读取xml文件小结
- tinyXML
- tinyxml
- TinyXml
- tinyxml
- TinyXML
- tinyxml
- tinyxml
- 栈的实现---java
- C++——函数调用堆栈
- GDAL+HDF4+HDF5+netCDF库编译C#
- day03-CSS-笔记1-选择器与文本元素
- 每日一练-20171025
- TinyXML用法小结
- linux操作小技巧
- js加载多个函数的问题
- linux和window下套接字的模式和他们之间的区别
- 43. Multiply Strings
- 学习vuex
- PAT1051 复数乘法
- HCCR
- 深入编译链接和运行