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);        }    }}
复制代码
分类: Xml,C++
好文要顶关注我 收藏该文
炽离
关注 - 0
粉丝 - 2
+加关注
0
0
«上一篇:dump文件生成与调试(VS2008)
»下一篇:gSoap工具wsdl2h及soapcpp2指令汇总

posted on 2016-09-02 15:21 炽离 阅读(4534) 评论(0)编辑 收藏