在《TinyXml快速入门(一)》中我介绍了使用TinyXml库如何创建和打印xml文件,下面我介绍使用tinyxml库对xml文件进行一系列的操作,包括获取xml文件声明,查询指定节点、删除指定节点、修改指定节点和增加节点的用法。在《TinyXml快速入门(一)》中我们知道xml文件中的一个节点元素实际包含两种值:属性和文本。其中属性在我看来可以看作是STL中的map,一个属性带一个属性值,map中也是一个键带一个键值。因此查询指定节点、删除指定节点和增加节点必然是需要实现两种方法,删除指定节点只需要实现一种方法。鉴于内容较多,在本文中介绍获取xml文件声明,查询指定节点、删除指定节点的做法,修改指定节点和增加节点的做法在后续的文章介绍。

首先是获取xml文件声明。xml文件声明包括三方面的内容:Version、Standalone和Encoding。其源码如下:

/*!
*  \brief 获取xml文件的声明。
*
*  \param XmlFile xml文件全路径。
*  \param strVersion  Version属性值
*  \param strStandalone Standalone属性值
*  \param strEncoding Encoding属性值
*  \return 是否成功。true为成功,false表示失败。
*/
bool GetXmlDeclare(std::string XmlFile,
                   std::string &strVersion,
                   std::string &strStandalone,
                   std::string &strEncoding)
{
    // 定义一个TiXmlDocument类指针
    TiXmlDocument *pDoc = new TiXmlDocument();
    if (NULL==pDoc)
    {
        return false;
    }     pDoc->LoadFile(XmlFile);       TiXmlNode* pXmlFirst = pDoc->FirstChild();   
      if (NULL != pXmlFirst)  
     {  
          TiXmlDeclaration* pXmlDec = pXmlFirst->ToDeclaration();  
          if (NULL != pXmlDec)  
          {  
              strVersion = pXmlDec->Version();
              strStandalone = pXmlDec->Standalone();
              strEncoding = pXmlDec->Encoding();
          }
      }
      return true;
}

我们发现无论查询节点、删除节点、修改节点和增加节点,其实都离不开一个函数,就是根据节点名获取相关节点指针。那么我们就先实现一个根据节点名获取节点指针的函数:

/*!
*  \brief 通过根节点和节点名获取节点指针。
*
*  \param pRootEle   xml文件的根节点。
*  \param strNodeName  要查询的节点名
*  \param Node      需要查询的节点指针
*  \return 是否找到。true为找到相应节点指针,false表示没有找到相应节点指针。
*/
bool GetNodePointerByName(TiXmlElement* pRootEle,std::string &strNodeName,TiXmlElement* &Node)
{
     // 假如等于根节点名,就退出
     if (strNodeName==pRootEle->Value())
     {
         Node = pRootEle;
         return true;
     }       TiXmlElement* pEle = pRootEle;  
      for (pEle = pRootEle->FirstChildElement(); pEle; pEle = pEle->NextSiblingElement())  
    {  
          //递归处理子节点,获取节点指针
          if(GetNodePointerByName(pEle,strNodeName,Node))
              return true;
     }        return false;
}

有了这个函数,我们就很容易实现查询节点的相应文本或属性值。

    /*!
*  \brief 通过节点查询。
*
*  \param XmlFile   xml文件全路径。
*  \param strNodeName  要查询的节点名
*  \param strText      要查询的节点文本
*  \return 是否成功。true为成功,false表示失败。
*/
bool QueryNode_Text(std::string XmlFile,std::string strNodeName,std::string &strText)
{
    // 定义一个TiXmlDocument类指针
    TiXmlDocument *pDoc = new TiXmlDocument();
    if (NULL==pDoc)
    {
        return false;
    }     pDoc->LoadFile(XmlFile);
    TiXmlElement *pRootEle = pDoc->RootElement();
    if (NULL==pRootEle)
    {
        return false;
    }    TiXmlElement *pNode = NULL;
   GetNodePointerByName(pRootEle,strNodeName,pNode);
   if (NULL!=pNode)
   {
        const char* psz = pNode->GetText(); 
       if (NULL==psz)
       {
        strText = _T("");
        }
       else
       {
         strText = psz;
        }
        return true;
   }
   else
   {
        return false;
   }
    
} /*!
*  \brief 通过节点查询。
*
*  \param XmlFile   xml文件全路径。
*  \param strNodeName  要查询的节点名
*  \param AttMap      要查询的属性值,这是一个map,前一个为属性名,后一个为属性值
*  \return 是否成功。true为成功,false表示失败。
*/
bool QueryNode_Attribute(std::string XmlFile,std::string strNodeName,std::map<std::string,std::string> &AttMap)
{
    // 定义一个TiXmlDocument类指针
    typedef std::pair <std::string,std::string> String_Pair;     TiXmlDocument *pDoc = new TiXmlDocument();
    if (NULL==pDoc)
    {
        return false;
    }     pDoc->LoadFile(XmlFile);
    TiXmlElement *pRootEle = pDoc->RootElement();
    if (NULL==pRootEle)
    {
        return false;
    }     TiXmlElement *pNode = NULL;     GetNodePointerByName(pRootEle,strNodeName,pNode);     if (NULL!=pNode)
    {
        TiXmlAttribute* pAttr = NULL; 
        for (pAttr = pNode->FirstAttribute(); pAttr; pAttr = pAttr->Next())  
        {  
            std::string strAttName = pAttr->Name();
            std::string strAttValue = pAttr->Value();
            AttMap.insert(String_Pair(strAttName,strAttValue));
        }  
        return true;
    }
    else
    {
        return false;
    }
    return true;
}

下面是删除指定节点的函数,其中考虑了删除根节点的情况。

/*!
*  \brief 删除指定节点的值。
*
*  \param XmlFile xml文件全路径。
*  \param strNodeName 指定的节点名。
*  \return 是否成功。true为成功,false表示失败。
*/
bool DelNode(std::string XmlFile,std::string strNodeName)
{
    // 定义一个TiXmlDocument类指针
    TiXmlDocument *pDoc = new TiXmlDocument();
    if (NULL==pDoc)
    {
        return false;
    }     pDoc->LoadFile(XmlFile);
    TiXmlElement *pRootEle = pDoc->RootElement();
    if (NULL==pRootEle)
    {
        return false;
    }     TiXmlElement *pNode = NULL;     GetNodePointerByName(pRootEle,strNodeName,pNode);     // 假如是根节点
    if (pRootEle==pNode)
    {
          if(pDoc->RemoveChild(pRootEle))
          {
               pDoc->SaveFile(XmlFile);
               return true;
          }
          else 
              return false;
    }     // 假如是其它节点
    if (NULL!=pNode)
    {
        TiXmlNode *pParNode =  pNode->Parent();
        if (NULL==pParNode)
        {
               return false;
        }
            
        TiXmlElement* pParentEle = pParNode->ToElement();
        if (NULL!=pParentEle)
        {
            if(pParentEle->RemoveChild(pNode))
                 pDoc->SaveFile(XmlFile);
            else
                return false;
        }
    }
    else
    {
          return false;
    }      return false;
}
 
 

TinyXml快速入门(二)的更多相关文章

  1. TinyXml 快速入门(三)

    在<TinyXml 快速入门(二)>介绍使用tinyxml库获取xml文件声明,查询指定节点.删除指定节点的做法.在本文中继续介绍修改指定节点和增加节点的做法. 修改节点其实和查询指定节点 ...

  2. 将TinyXml快速入门的接口面向对象化(转载)

    作者:朱金灿 来源:http://www.cnblogs.com/clever101 在TinyXml快速入门的系列文章中(详情见本博客),我只是将tinyxml类库解析xml文件的类封装为API接口 ...

  3. python3.5+django2.0快速入门(二)

    昨天写了python3.5+django2.0快速入门(一)今天将讲解配置数据库,创建模型,还有admin的后台管理. 配置数据库 我们打开mysite/mysite/settings.py这个文件. ...

  4. TinyXml快速入门(一)

    对于xml文件,目前的工作只是集中在配置文件和作为简单的信息文件来用,因此我不太喜欢使用msxml这种重量级的xml解析器,特别是使用msxml解析xml涉及到复杂的com类型转换,更是令人感觉繁琐. ...

  5. Linux Bash Shell快速入门 (二)

    BASH 中的变量介绍BASH 中的变量都是不能含有保留字,不能含有 "-" 等保留字符,也不能含有空格. 简单变量在 BASH 中变量定义是不需要的,没有 "int i ...

  6. Mysql快速入门(二)

    多表关联查询 JOIN 按照功能大致分为如下三类: CROSS JOIN(交叉连接) INNER JOIN(内连接或等值连接). OUTER JOIN(外连接) 交叉连接 交叉连接的关键字:CROSS ...

  7. Ant快速入门(二)-----使用Ant工具

    使用Ant非常简单,当正确安装Ant后,只要输入ant或ant.bat即可. 如果运行ant命令时没有指定任何参数,Ant会在当前目录下搜索build.xml文件.如果找到了就以该文件作为生成文件,并 ...

  8. mybatis快速入门(二)

    这次接着上次写增删改查吧. 现将上节的方法改造一下,改造测试类. package cn.my.test; import java.io.IOException; import java.io.Inpu ...

  9. jquery 快速入门二

    ---恢复内容开始--- 操作标签 样式操作 样式类 addClass();//添加指定的CSS类名. removeClass();//移除指定的类名. hasClass();//判断样式不存在 to ...

随机推荐

  1. iOS 中Window优先级的问题

    在项目中,视频播放时候遇到网络切换需要弹出AlertView提醒用户,忽然发现转屏的时候播放View加到KeyWindow的时候把AleryView挡住了.如图 因为转屏的时候视图是直接加载到 [UI ...

  2. ASP.NET菜鸟之路之实现新闻列表增删改

    背景 我是一个ASP.NET菜鸟,暂时开始学习ASP.NET,在此记录下我个人敲的代码,没有多少参考价值,请看到的盆友们为我点个赞支持我一下,多谢了. 网站介绍 根据视频的例子修改的方法,其中数据不经 ...

  3. onresize的定义方式

    1.直接在html中定义如<body onresize="doResize()"/> 2.直接给onresize赋值给window和body的onresize赋值如wi ...

  4. Bootstrap_排版_代码

    不管使用哪种代码风格,在代码中碰到小于号(<)要使用硬编码“<”来替代,大于号(>)使用“>”来替代 一.单行内联代码 <code>:一般是针对于单个单词或单个句子 ...

  5. js在html中的加载执行顺序

    1.加载顺序:引入标记<script />的出现顺序,依次加载 页面上的Javascript代码是HTML文档的一部分,所以Javascript在页面装载时执行的顺序就是其引入标记< ...

  6. easyui combo+pagination 图标选择器

    从数据库读取分页显示 $(function () { initTable(1, 180); $('#cc').combo({ editable: false, panelWidth: 'auto', ...

  7. 未能写入输出文件 c:/WINDOWS/Microsoft.NET/Framework/v2.0.50727/Temporary

    ERROR: 未能写入输出文件“c:/WINDOWS/Microsoft.NET/Framework/v2.0.50727/Temporary ASP.NET Files/root/.... 一般遇到 ...

  8. C# 代码 设置 前台 页面 JS提示

    方法1: Page.ClientScript.RegisterStartupScript(this.GetType(), "", "<script>alert ...

  9. spring mvc标准项目结构

    src com.xxx.inews.dao com.xxx.inews.dao.impl com.xxx.inews.data.entity com.xxx.inews.data.vo com.xxx ...

  10. windows10 预览版 中英文官方下载地址+激活密钥+网盘分享

    windows10 预览版 中英文官方下载地址+激活密钥+网盘分享 产品密钥:NKJFK-GPHP7-G8C3J-P6JXR-HQRJR 英语 64 位 (x64)  http://iso.esd.m ...