xml解析器tinyXML

转自:http://blog.163.com/kin_jiezi/blog/static/3683682201172593616285/

读取和设置xml配置文件是最常用的操作,试用了几个C++的XML解析器,个人感觉TinyXML是使用起来最舒服的,因为它的API接口和Java的十分类似,面向对象性很好。

TinyXML是一个开源的解析XML的解析库,能够用于C++,能够在Windows或Linux中编译。这个解析库的模型通过解析XML文件,然后在内存中生成DOM模型,从而让我们很方便的遍历这棵XML树。

DOM模型即文档对象模型,是将整个文档分成多个元素(如书、章、节、段等),并利用树型结构表示这些元素之间的顺序关系以及嵌套包含关系。

如下是一个XML片段:
    < Persons >
         < Person  ID ="1" >
             < name >周星星 </ name >
             < age >20 </ age >
         </ Person >
         < Person  ID ="2" >
             < name >白晶晶 </ name >
             < age >18 </ age >
         </ Person >
     </ Persons >

 在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的一些操作。

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来调用。举个例子就可以说明一切。。。

对应的XML文件:
< Persons >
     < Person  ID ="1" >
         < name >phinecos </ name >
         < age >22 </ age >
     </ Person >
</ Persons >

读写XML文件的程序代码:

#include <iostream>
#include  " tinyxml.h "
#include  " tinystr.h "
#include < string>
#include <windows.h>
#include <atlstr.h>
using  namespace std;

CString GetAppPath()
{//获取应用程序根目录
    TCHAR modulePath[MAX_PATH];
    GetModuleFileName(NULL, modulePath, MAX_PATH);
    CString strModulePath(modulePath);
    strModulePath = strModulePath.Left(strModulePath.ReverseFind(_T('\\')));
    return strModulePath;
}


bool CreateXmlFile( string& szFileName)
{//创建xml文件,szFilePath为文件保存的路径,若创建成功返回true,否则false
    try
    {
        //创建一个XML的文档对象。
        TiXmlDocument *myDocument = new TiXmlDocument();
        //创建一个根元素并连接。
        TiXmlElement *RootElement = new TiXmlElement("Persons");
        myDocument->LinkEndChild(RootElement);
        //创建一个Person元素并连接。
        TiXmlElement *PersonElement = new TiXmlElement("Person");
        RootElement->LinkEndChild(PersonElement);
        //设置Person元素的属性。
        PersonElement->SetAttribute("ID""1");
        //创建name元素、age元素并连接。
        TiXmlElement *NameElement = new TiXmlElement("name");
        TiXmlElement *AgeElement = new TiXmlElement("age");
        PersonElement->LinkEndChild(NameElement);
        PersonElement->LinkEndChild(AgeElement);
        //设置name元素和age元素的内容并连接。
        TiXmlText *NameContent = new TiXmlText("周星星");
        TiXmlText *AgeContent = new TiXmlText("22");
        NameElement->LinkEndChild(NameContent);
        AgeElement->LinkEndChild(AgeContent);
        CString appPath = GetAppPath();
        string seperator = "\\";
        string fullPath = appPath.GetBuffer(0) +seperator+szFileName;
        myDocument->SaveFile(fullPath.c_str());//保存到文件
    }

    catch (string& e)
    {
        return false;
    }

    return true;
}


bool ReadXmlFile( string& szFileName)
{//读取Xml文件,并遍历
    try
    {
        CString appPath = GetAppPath();
        string seperator = "\\";
        string fullPath = appPath.GetBuffer(0) +seperator+szFileName;
        //创建一个XML的文档对象。
        TiXmlDocument *myDocument = new TiXmlDocument(fullPath.c_str());
        myDocument->LoadFile();
        //获得根元素,即Persons。
        TiXmlElement *RootElement = myDocument->RootElement();
        //输出根元素名称,即输出Persons。
        cout << RootElement->Value() << endl;
        //获得第一个Person节点。
        TiXmlElement *FirstPerson = RootElement->FirstChildElement();
        //获得第一个Person的name节点和age节点和ID属性。
        TiXmlElement *NameElement = FirstPerson->FirstChildElement();
        TiXmlElement *AgeElement = NameElement->NextSiblingElement();
        TiXmlAttribute *IDAttribute = FirstPerson->FirstAttribute();
        //输出第一个Person的name内容,即周星星;age内容,即;ID属性,即。
        cout << NameElement->FirstChild()->Value() << endl;
        cout << AgeElement->FirstChild()->Value() << endl;
        cout << IDAttribute->Value()<< endl;
    }

    catch (string& e)
    {
        return false;
    }

    return true;
}

int main()
{
    string fileName = "info.xml";
    CreateXmlFile(fileName);
    ReadXmlFile(fileName);
}

1.首先下载TinyXML库的文件,这里给出链接,大家自己去下吧
http://prdownloads.sourceforge.net/tinyxml

2.在TinyXML的目录里面找到tinystr.h, tinyxml.h, tinystr.cpp, tinyxml.cpp, tinyxmlerror.cpp, tinyxmlparser.cpp六个文件加入到刚刚创建的项目中去

3.在相应的工程文件中加入两个头文件
#include "tinyxml.h"
#include "tinystr.h"

4.tinystr.cpp, tinyxml.cpp, tinyxmlerror.cpp, tinyxmlparser.cpp六个文件的第一行加入头文件
#include "stdafx.h"
至于为什么,在vc的win32工程cpp文件中,如果不加该文件头的话会提示文件没有结束标志

在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" standalone=no>
<!– Our to do list data –>
<ToDo>
<Item priority="1"> Go to the <bold>Toy store!</bold></Item>
<Item priority="2"> Do bills</Item>
</ToDo> 



整个对象树: 

TiXmlDocument "demo.xml"
TiXmlDeclaration "version=’1.0′" "standalone=no"
TiXmlComment " Our to do list data"
TiXmlElement "ToDo"
TiXmlElement "Item" Attribtutes: priority = 1
TiXmlText "Go to the "
TiXmlElement "bold"
TiXmlText "Toy store!"
TiXmlElement "Item" Attributes: priority=2
TiXmlText "Do bills" 

tinyXML中,用FirstChild"名字"时,FirstChild函数的点与要找的点必父子

句柄

想要健壮地读取一个XML文档,检查方法调用后的返回值是否为null是很重要的。一种安全的检错实现可能会产生像这样的代码: 

 

TiXmlElement *  root  =  document.FirstChildElement(  " Document "  );
if  ( root )
{
TiXmlElement
* element = root->FirstChildElement( "Element" );
if ( element )
{
TiXmlElement
* child = element->FirstChildElement( "Child" );
if ( child )
{
TiXmlElement
* child2 = child->NextSiblingElement( "Child" );
if ( child2 )
{
// Finally do something useful. 



用句柄的话就不会这么冗长了,使用TiXmlHandle类,前面的代码就会变成这样: 

TiXmlHandle docHandle(  & document );
TiXmlElement
*  child2  =  docHandle.FirstChild(  " Document "  ).FirstChild(  " Element "  ).Child(  " Child " 1  ).ToElement();
if  ( child2 )
{
// do something useful 

一、读取XML,设置节点文本
如下XML片段:

<? xml version="1.0" encoding="UTF-8" standalone="yes"  ?>
< ZXML >
    
< ZAPP >
         
< VBS_RUNTIME_PARAMS >
               
< BROADCAST_VERSION  info ="版本" > 8 </ BROADCAST_VERSION >
               
< Broadcast >
                
< FileCount  info ="资源文件个数" > 69 </ FileCount >
                
< SOURCE_1 >
                    
< ID  info ="图片编号" > 1 </ ID >
                    
< Version  info ="图片版本" > 1 </ Version >
                    
< Path  info ="图片路径" > /mnt/share/1.bmp </ Path >
                    
< FileMode  info ="文件处理模式" > 0 </ FileMode >
                
</ SOURCE_1 >
                
< SOURCE_2 >
                    
< Path  info ="图片路径" > /mnt/share/2.bmp </ Path >
                    
< ID  info ="图片编号" > 2 </ ID >
                    
< Version  info ="图片版本" > 1 </ Version >
                    
< FileMode  info ="文件处理模式" > 0 </ FileMode >
                
</ SOURCE_2 >
                .
                
</ Broadcast >
         
</ VBS_RUNTIME_PARAMS >
    
</ ZAPP >
</ ZXML >


要设置BROADCAST_VERSION节点的值 8为其他值,可参考如下代码(将值加1):
用ReplaceChild( TiXmlNode* replaceThis, const TiXmlNode& withThis )方法替换

     TiXmlDocument doc("zapp.conf");
    doc.LoadFile();
    TiXmlHandle docHandle( 
& doc );
TiXmlElement
*  Broadcast_ver  =  docHandle.FirstChild( " ZXML " ).FirstChild( " ZAPP " ).FirstChild( " VBS_RUNTIME_PARAMS " ).FirstChildElement( " BROADCAST_VERSION " ).ToElement();
    TiXmlNode 
*  oldnode  =   Broadcast_ver -> FirstChild();
    
const   char   * ver  =  Broadcast_ver -> GetText();
    
int  oldVer  =  atoi(ver);
    CString newVer;
    newVer.Format(
" %d " ,oldVer + 1 );
    TiXmlText newText(newVer);
    Broadcast_ver
-> ReplaceChild(oldnode,newText);
    AfxMessageBox(Broadcast_ver
-> GetText()); // 输出值
    
doc.SaveFile();

二,删除节点,属性值

RemoveChild( TiXmlNode* removeThis )方法删除父节点的子节点,
RemoveAttribute( const char * name )方法删除属性值.

例如删除BROADCAST_VERSION节点

TiXmlHandle docHandle(  & doc );
    TiXmlElement
*  Broadcast_ver  =  docHandle.FirstChild( " ZXML " ).FirstChild( " ZAPP " ).FirstChild( " VBS_RUNTIME_PARAMS " ).ToElement();

    TiXmlNode 
*  node  =   Broadcast_ver -> FirstChild( " BROADCAST_VERSION " );

    Broadcast_ver
-> RemoveChild(node);

也可以删除整个SOURCE_1节点:

TiXmlHandle docHandle(  & doc );
    TiXmlElement
*  Broadcast  =  docHandle.FirstChild( " ZXML " ).FirstChild( " ZAPP " ).FirstChild( " VBS_RUNTIME_PARAMS " ).FirstChild( " Broadcast " ).ToElement();

    TiXmlNode 
*  node  =   Broadcast -> FirstChild( " SOURCE_1 " );

    Broadcast
-> RemoveChild(node);

删除BROADCAST_VERSION的info属性:

TiXmlHandle docHandle(  & doc );
    TiXmlElement
*  Broadcast_ver  =  docHandle.FirstChild( " ZXML " ).FirstChild( " ZAPP " ).FirstChild( " VBS_RUNTIME_PARAMS " ).FirstChildElement( " BROADCAST_VERSION " ).ToElement();

    Broadcast_ver
-> RemoveAttribute( " info " );  // 删除info

可以借助NextSiblingElement()方法实现递归删除.

三,添加节点,属性值

例如在SOURCE_3下添加BROADCAST_PID节点:

TiXmlHandle docHandle(  & doc );
    TiXmlElement
*  Broadcast  =  docHandle.FirstChild( " ZXML " ).FirstChild( " ZAPP " ).FirstChild( " VBS_RUNTIME_PARAMS " ).FirstChild( " Broadcast " ).ToElement();
    TiXmlElement
*  Broadcast_Pid  =   new  TiXmlElement( " BROADCAST_PID " );
    TiXmlText 
* text  = new  TiXmlText( " 7215 " );
    Broadcast_Pid
-> SetAttribute( " info " , " the pid " );
    Broadcast_Pid
-> LinkEndChild(text);
    Broadcast
-> LinkEndChild(Broadcast_Pid);

将在SOURCE_3后添加新的节点:

< BROADCAST_PID  info ="the pid" > 7215 </ BROADCAST_PID >

四,最后说一下中文乱码的问题

乱码是由于GB2312与UTF8之间转换不当造成的,tinyxml在处理UTF8本身没有问题,当你打开一个UTF8的文档,可以在加载的时候指定UTF8的方式,或者文档声明处指明的编码格式,tinyxml会按照相应的编码格式加载,但很多时候当我们输出或写入中文字段时会出现乱码,无论在内存,还是打印出来的内容.这是因为我们的软件通常是GB2312编码,而读取或写入的内容是UTF8,自然就会出错.可以借助网上的两个函数来实现转换(原作者不详):

     void  ConvertUtf8ToGBK(CString &  strUtf8) 
    
{
        
int len=MultiByteToWideChar(CP_UTF8, 0, (LPCTSTR)strUtf8, -1, NULL,0);
        unsigned 
short * wszGBK = new unsigned short[len+1];
        memset(wszGBK, 
0, len * 2 + 2);
        MultiByteToWideChar(CP_UTF8, 
0, (LPCTSTR)strUtf8, -1, wszGBK, len);

        len 
= WideCharToMultiByte(CP_ACP, 0, wszGBK, -1, NULL, 0, NULL, NULL);
        
char *szGBK=new char[len + 1];
        memset(szGBK, 
0, len + 1);
        WideCharToMultiByte (CP_ACP, 
0, wszGBK, -1, szGBK, len, NULL,NULL);

        strUtf8 
= szGBK;
        delete[] szGBK;
        delete[] wszGBK;
    }



    
void  ConvertGBKToUtf8(CString &  strGBK)
    
{
        
int len=MultiByteToWideChar(CP_ACP, 0, (LPCTSTR)strGBK, -1, NULL,0);
        unsigned 
short * wszUtf8 = new unsigned short[len+1];
        memset(wszUtf8, 
0, len * 2 + 2);
        MultiByteToWideChar(CP_ACP, 
0, (LPCTSTR)strGBK, -1, wszUtf8, len);

        len 
= WideCharToMultiByte(CP_UTF8, 0, wszUtf8, -1, NULL, 0, NULL, NULL);
        
char *szUtf8=new char[len + 1];
        memset(szUtf8, 
0, len + 1);
        WideCharToMultiByte (CP_UTF8, 
0, wszUtf8, -1, szUtf8, len, NULL,NULL);

        strGBK 
= szUtf8;
        delete[] szUtf8;
        delete[] wszUtf8;
    }



现在越来越多的数据和配置采用了xml格式来存放和进行传输解析了。在c++方面,没有本地支持的库,所以需要我们自己去找一下。微软的msxml说实话,确实不咋地,尤其是com的类型变量名字一直指针,让众人看上去就比较反感。开源的tinyxml在这方便做的还不错。简单介绍下使用过程的一点小经验。

在这里发下牢骚,VC6.0以后的各个版本的VS环境对于C++的智能感知都是那么的SB,不管你怎么配置,怎么google都让你非常抓狂,就是不出来。算了不说了。


从网站上下载tinyxml,下载之后解压打开文件夹,里面有一些测试例子,tinyxml.sln支持vs2010了都,不管这些,怎么需要的是那个xml类库。

使用tinyxml我们只需要

tinyxml.cpp, 

tinyxml.h

tinyxmlerror.cpp, 

tinyxmlparser.cpp, 

tinystr.cpp, 

tinystr.h

6个文件即可。注意一旦少拷贝了其中tinyxmlerror.cpp, tinyxmlparser.cpp, 其中一个或者两个,就会报告link错误,呵呵

在目标源文件的头部,添加 #include"tinyxml.h"和#include "tinystr.h"


我们使用xml文件,无外乎这几种操作,

1. 遍历整个xml返回一棵树select

2. 查找特定节点的属性/文本值select

3.插入特定位置一个节点insert

4.更新特定节点的属性/文本值 update

5.创建xml文件 create

6.who knows


据一位网友的博文里面提到,基本应该涵盖数据库的所有操作,xml操作应该像操作数据库一样。我觉得甚是有道理啊。

那么我来列举下,我搜集以及测试成功的相关的操作代码吧,希望能节省一些大家学习的时间。


1.create xml操作

[cpp]  view plain copy
  1. // 定义一个TiXmlDocument类指针    
  2.    TiXmlDocument *pDoc = new TiXmlDocument;    
  3.    if (NULL==pDoc)    
  4.    {    
  5.        return false;    
  6.    }    
  7.   
  8.    // 定义一个xml文件头部声明  
  9.    TiXmlDeclaration *pDeclaration = new TiXmlDeclaration(("1.0"),(""),(""));    
  10.    if (NULL==pDeclaration)    
  11.    {    
  12.        return false;    
  13.    }  
  14.    
  15.    pDoc->LinkEndChild(pDeclaration);    
  16.   
  17.    // 生成一个根节点:MyApp    
  18.    TiXmlElement *pRootEle = new TiXmlElement(("MyApp"));    
  19.    if (NULL==pRootEle)    
  20.    {    
  21.        return false;    
  22.    }    
  23.    pDoc->LinkEndChild(pRootEle);  
  24.    
  25.    // 生成子节点:Messages    
  26.    TiXmlElement *pMsg = new TiXmlElement(("Messages"));    
  27.    if (NULL==pMsg)    
  28.    {    
  29.        return false;    
  30.    }    
  31.    pRootEle->LinkEndChild(pMsg);    
  32.   
  33.    // 生成子节点:Welcome    
  34.    TiXmlElement *pWelcome = new TiXmlElement(("Welcome"));    
  35.    if (NULL==pWelcome)    
  36.    {    
  37.        return false;    
  38.    }    
  39.    pMsg->LinkEndChild(pWelcome);    
  40.   
  41.    // 设置Welcome节点的值    
  42.    const char* strValue = ("Welcome to MyApp");    
  43.    TiXmlText *pWelcomeValue = new TiXmlText(strValue);    
  44.    pWelcome->LinkEndChild(pWelcomeValue);    
  45.   
  46.    // 生成子节点:Farewell    
  47.    TiXmlElement *pFarewell = new TiXmlElement(("Farewell"));    
  48.    if (NULL==pFarewell)    
  49.    {    
  50.        return false;    
  51.    }    
  52.    pMsg->LinkEndChild(pFarewell);   
  53.   
  54.    // 设置Farewell节点的值    
  55.    strValue = ("Thank you for using MyApp");    
  56.    TiXmlText *pFarewellValue = new TiXmlText(strValue);    
  57.    pFarewell->LinkEndChild(pFarewellValue);    
  58.   
  59.    // 生成子节点:Windows    
  60.    TiXmlElement *pWindows = new TiXmlElement(("Windows"));    
  61.    if (NULL==pWindows)    
  62.    {    
  63.        return false;    
  64.    }    
  65.    pRootEle->LinkEndChild(pWindows);    
  66.   
  67.    // 生成子节点:Window    
  68.    TiXmlElement *pWindow = new TiXmlElement(("Window"));    
  69.    if (NULL==pWindow)    
  70.    {    
  71.        return false;    
  72.    }    
  73.    pWindows->LinkEndChild(pWindow);   
  74.   
  75.    // 设置节点Window的值    
  76.    pWindow->SetAttribute(("name"),("MainFrame"));    
  77.    pWindow->SetAttribute(("x"),("5"));    
  78.    pWindow->SetAttribute(("y"),("15"));    
  79.    pWindow->SetAttribute(("w"),("400"));    
  80.    pWindow->SetAttribute(("h"),("250"));  
  81.    
  82.    // 生成子节点:Window    
  83.    TiXmlElement *pConnection  = new TiXmlElement(("Connection"));    
  84.    if (NULL==pConnection)    
  85.    {    
  86.        return false;    
  87.    }    
  88.    pRootEle->LinkEndChild(pConnection);    
  89.   
  90.    // 设置节点Connection的值    
  91.    pConnection->SetAttribute(("ip"),("192.168.0.1"));    
  92.    pConnection->SetAttribute(("timeout"),("123.456000"));    
  93.    pDoc->SaveFile("1.xml");    

2.遍历打印xml文件 select操作

[cpp]  view plain copy
  1. //TiXmlDocument *pDoc = new TiXmlDocument();    
  2.     if (NULL==pDoc)    
  3.     {    
  4.         return false;    
  5.     }    
  6.     pDoc->LoadFile("1.xml");    
  7.     pDoc->Print();    

3.获取单个节点值

[cpp]  view plain copy
  1. bool GetNodePointerByName(TiXmlElement* pRootEle,std::string &strNodeName,TiXmlElement* &Node)    
  2. {    
  3.      // 假如等于根节点名,就退出    
  4.      if (strNodeName==pRootEle->Value())    
  5.      {    
  6.          Node = pRootEle;    
  7.          return true;    
  8.      }    
  9.       TiXmlElement* pEle = pRootEle;      
  10.       for (pEle = pRootEle->FirstChildElement(); pEle; pEle = pEle->NextSiblingElement())      
  11.     {      
  12.           //递归处理子节点,获取节点指针    
  13.           if(GetNodePointerByName(pEle,strNodeName,Node))    
  14.               return true;    
  15.      }      
  16.      return false;    
  17. }     

[cpp]  view plain copy
  1. bool QueryNode_Text(std::string XmlFile,std::string strNodeName,std::string &strText)    
  2. {    
  3.     // 定义一个TiXmlDocument类指针    
  4.     TiXmlDocument *pDoc = new TiXmlDocument();    
  5.     if (NULL==pDoc)    
  6.     {    
  7.         return false;    
  8.     }    
  9.     pDoc->LoadFile(XmlFile);    
  10.     TiXmlElement *pRootEle = pDoc->RootElement();    
  11.     if (NULL==pRootEle)    
  12.     {    
  13.         return false;    
  14.     }    
  15.    TiXmlElement *pNode = NULL;    
  16.    GetNodePointerByName(pRootEle,strNodeName,pNode);    
  17.    if (NULL!=pNode)    
  18.    {    
  19.         strText = pNode->GetText();     
  20.         return true;    
  21.    }    
  22.    else    
  23.    {    
  24.         return false;    
  25.    }    
  26.         
  27. }    

[cpp]  view plain copy
  1. bool QueryNode_Attribute(std::string XmlFile,std::string strNodeName,std::map<std::string,std::string> &AttMap)    
  2. {    
  3.     // 定义一个TiXmlDocument类指针    
  4.     typedef std::pair <std::string,std::string> String_Pair;    
  5.     TiXmlDocument *pDoc = new TiXmlDocument();    
  6.     if (NULL==pDoc)    
  7.     {    
  8.         return false;    
  9.     }    
  10.     pDoc->LoadFile(XmlFile);    
  11.     TiXmlElement *pRootEle = pDoc->RootElement();    
  12.     if (NULL==pRootEle)    
  13.     {    
  14.         return false;    
  15.     }    
  16.     TiXmlElement *pNode = NULL;    
  17.     GetNodePointerByName(pRootEle,strNodeName,pNode);    
  18.     if (NULL!=pNode)    
  19.     {    
  20.         TiXmlAttribute* pAttr = NULL;     
  21.         for (pAttr = pNode->FirstAttribute(); pAttr; pAttr = pAttr->Next())      
  22.         {      
  23.             std::string strAttName = pAttr->Name();    
  24.             std::string strAttValue = pAttr->Value();    
  25.             AttMap.insert(String_Pair(strAttName,strAttValue));    
  26.         }      
  27.         return true;    
  28.     }    
  29.     else    
  30.     {    
  31.         return false;    
  32.     }    
  33.     return true;    
  34. }    

4.删除节点操作

[cpp]  view plain copy
  1. bool DelNode(std::string XmlFile,std::string strNodeName)    
  2. {    
  3.     // 定义一个TiXmlDocument类指针    
  4.     TiXmlDocument *pDoc = new TiXmlDocument();    
  5.     if (NULL==pDoc)    
  6.     {    
  7.         return false;    
  8.     }    
  9.     pDoc->LoadFile(XmlFile);    
  10.     TiXmlElement *pRootEle = pDoc->RootElement();    
  11.     if (NULL==pRootEle)    
  12.     {    
  13.         return false;    
  14.     }    
  15.     TiXmlElement *pNode = NULL;    
  16.     GetNodePointerByName(pRootEle,strNodeName,pNode);    
  17.     // 假如是根节点    
  18.     if (pRootEle==pNode)    
  19.     {    
  20.           if(pDoc->RemoveChild(pRootEle))    
  21.           {    
  22.                pDoc->SaveFile(XmlFile);    
  23.                return true;    
  24.           }    
  25.           else     
  26.               return false;    
  27.     }    
  28.     // 假如是其它节点    
  29.     if (NULL!=pNode)    
  30.     {    
  31.         TiXmlNode *pParNode =  pNode->Parent();    
  32.         if (NULL==pParNode)    
  33.         {    
  34.                return false;    
  35.         }    
  36.                 
  37.         TiXmlElement* pParentEle = pParNode->ToElement();    
  38.         if (NULL!=pParentEle)    
  39.         {    
  40.             if(pParentEle->RemoveChild(pNode))    
  41.                  pDoc->SaveFile(XmlFile);    
  42.             else    
  43.                 return false;    
  44.         }    
  45.     }    
  46.     else    
  47.     {    
  48.           return false;    
  49.     }    
  50.      return false;    
  51. }    

5.修改节点操作

[cpp]  view plain copy
  1. bool ModifyNode_Text(std::string XmlFile,std::string strNodeName,std::string strText)    
  2. {    
  3.     // 定义一个TiXmlDocument类指针    
  4.     TiXmlDocument *pDoc = new TiXmlDocument();    
  5.     if (NULL==pDoc)    
  6.     {    
  7.         return false;    
  8.     }    
  9.     pDoc->LoadFile(XmlFile);    
  10.     TiXmlElement *pRootEle = pDoc->RootElement();    
  11.     if (NULL==pRootEle)    
  12.     {    
  13.         return false;    
  14.     }    
  15.     TiXmlElement *pNode = NULL;    
  16.     GetNodePointerByName(pRootEle,strNodeName,pNode);    
  17.     if (NULL!=pNode)    
  18.     {    
  19.         pNode->Clear();  // 首先清除所有文本    
  20.         // 然后插入文本,保存文件    
  21.         TiXmlText *pValue = new TiXmlText(strText);    
  22.         pNode->LinkEndChild(pValue);    
  23.         pDoc->SaveFile(XmlFile);    
  24.         return true;    
  25.     }    
  26.     else    
  27.         return false;    
  28. }    

[cpp]  view plain copy
  1. bool ModifyNode_Attribute(std::string XmlFile,std::string strNodeName,    
  2.                  std::map<std::string,std::string> &AttMap)    
  3. {    
  4.     typedef std::pair <std::string,std::string> String_Pair;    
  5.     // 定义一个TiXmlDocument类指针    
  6.     TiXmlDocument *pDoc = new TiXmlDocument();    
  7.     if (NULL==pDoc)    
  8.     {    
  9.         return false;    
  10.     }    
  11.     pDoc->LoadFile(XmlFile);    
  12.     TiXmlElement *pRootEle = pDoc->RootElement();    
  13.     if (NULL==pRootEle)    
  14.     {    
  15.         return false;    
  16.     }    
  17.      
  18.     TiXmlElement *pNode = NULL;    
  19.     GetNodePointerByName(pRootEle,strNodeName,pNode);    
  20.     if (NULL!=pNode)    
  21.     {    
  22.         TiXmlAttribute* pAttr = NULL;     
  23.         std::string strAttName = _T("");    
  24.         std::string strAttValue = _T("");    
  25.         for (pAttr = pNode->FirstAttribute(); pAttr; pAttr = pAttr->Next())      
  26.         {      
  27.             strAttName = pAttr->Name();    
  28.             std::map<std::string,std::string>::iterator iter;    
  29.             for (iter=AttMap.begin();iter!=AttMap.end();iter++)    
  30.             {    
  31.                 if (strAttName==iter->first)    
  32.                 {    
  33.                     pAttr->SetValue(iter->second);    
  34.                 }    
  35.             }    
  36.         }      
  37.         pDoc->SaveFile(XmlFile);    
  38.         return true;    
  39.     }    
  40.     else    
  41.     {    
  42.         return false;    
  43.     }    
  44. }    

6增加节点操作

[cpp]  view plain copy
  1. bool AddNode_Text(std::string XmlFile,std::string strParNodeName,std::string strNodeName,std::string strText)    
  2. {    
  3.     // 定义一个TiXmlDocument类指针    
  4.     TiXmlDocument *pDoc = new TiXmlDocument();    
  5.     if (NULL==pDoc)    
  6.     {    
  7.         return false;    
  8.     }    
  9.     pDoc->LoadFile(XmlFile);    
  10.     TiXmlElement *pRootEle = pDoc->RootElement();    
  11.     if (NULL==pRootEle)    
  12.     {    
  13.         return false;    
  14.     }    
  15.     TiXmlElement *pNode = NULL;    
  16.     GetNodePointerByName(pRootEle,strParNodeName,pNode);    
  17.     if (NULL!=pNode)    
  18.     {    
  19.         // 生成子节点:pNewNode    
  20.         TiXmlElement *pNewNode = new TiXmlElement(strNodeName);    
  21.         if (NULL==pNewNode)    
  22.         {    
  23.             return false;    
  24.         }    
  25.         // 设置节点文本,然后插入节点    
  26.         TiXmlText *pNewValue = new TiXmlText(strText);    
  27.         pNewNode->LinkEndChild(pNewValue);    
  28.         pNode->InsertEndChild(*pNewNode);    
  29.         pDoc->SaveFile(XmlFile);    
  30.         return true;    
  31.     }    
  32.     else    
  33.          return false;    
  34.         
  35. }    

[cpp]  view plain copy
  1. bool AddNode_Attribute(std::string XmlFile,std::string strParNodeName,std::string strNodeName,std::map<std::string,std::string> &AttMap)    
  2. {    
  3.     // 定义一个TiXmlDocument类指针    
  4.     TiXmlDocument *pDoc = new TiXmlDocument();    
  5.     if (NULL==pDoc)    
  6.     {    
  7.         return false;    
  8.     }    
  9.     pDoc->LoadFile(XmlFile);    
  10.     TiXmlElement *pRootEle = pDoc->RootElement();    
  11.     if (NULL==pRootEle)    
  12.     {    
  13.         return false;    
  14.     }    
  15.     TiXmlElement *pNode = NULL;    
  16.     GetNodePointerByName(pRootEle,strParNodeName,pNode);    
  17.     if (NULL!=pNode)    
  18.     {    
  19.         // 生成子节点:pNewNode    
  20.         TiXmlElement *pNewNode = new TiXmlElement(strNodeName);    
  21.         if (NULL==pNewNode)    
  22.         {    
  23.             return false;    
  24.         }    
  25.         // 设置节点的属性值,然后插入节点    
  26.         std::map<std::string,std::string>::iterator iter;    
  27.         for (iter=AttMap.begin();iter!=AttMap.end();iter++)    
  28.         {    
  29.              pNewNode->SetAttribute(iter->first,iter->second);    
  30.         }    
  31.         pNode->InsertEndChild(*pNewNode);    
  32.         pDoc->SaveFile(XmlFile);    
  33.         return true;    
  34.     }    
  35.     else    
  36.         return false;    
  37. }    

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值