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

 

     修改节点其实和查询指定节点的值有点类似,也分为两个函数,一个实现修改文本。另一个负责修改属性。



/*!

*  \brief 修改指定节点的文本。

*

*  \param XmlFile xml文件全路径。

*  \param strNodeName 指定的节点名。

*  \param strText 重新设定的文本的值

*  \return 是否成功。true为成功,false表示失败。

*/

bool ModifyNode_Text(const std::string& XmlFile,const std::string& strNodeName,const 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)

    {

        pNode->Clear();  // 首先清除所有文本

        // 然后插入文本,保存文件

        TiXmlText *pValue = new TiXmlText(strText);

        pNode->LinkEndChild(pValue);

        pDoc->SaveFile(XmlFile);

        return true;

    }

    else

        return false;

}



/*!

*  \brief 修改指定节点的属性值。

*

*  \param XmlFile xml文件全路径。

*  \param strNodeName 指定的节点名。

*  \param AttMap 重新设定的属性值,这是一个map,前一个为属性名,后一个为属性值

*  \return 是否成功。true为成功,false表示失败。

*/

bool ModifyNode_Attribute(const std::string& XmlFile,const std::string& strNodeName,

                 const std::map<std::string,std::string> &AttMap)

{

    typedef std::pair <std::string,std::string> String_Pair;


    // 定义一个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)

    {

        TiXmlAttribute* pAttr = NULL; 

        std::string strAttName = _T("");

        std::string strAttValue = _T("");

        for (pAttr = pNode->FirstAttribute(); pAttr; pAttr = pAttr->Next())  

        {  

            strAttName = pAttr->Name();


            std::map<std::string,std::string>::const_iterator iter;

            for (iter=AttMap.begin();iter!=AttMap.end();iter++)

            {

                if (strAttName==iter->first)

                {

                    pAttr->SetValue(iter->second);

                }

            }


        }  

        pDoc->SaveFile(XmlFile);

        return true;

    }

    else

    {

        return false;

    }


}


 

对于ModifyNode_Attribute函数,这里稍微介绍一下如何使用,比如对于下面这样一个xml文件:



<?xml version="1.0" encoding="utf-8" standalone="yes" ?>

<MyApp>

    <Messages>

        <Welcome>Welcome to MyApp</Welcome>

        <Farewell>Thank you for using MyApp</Farewell>

    </Messages>

    <Windows>

        <Window name="MainFrame" x="5" y="15" w="400" h="250" />

    </Windows>

    <Connection ip="192.168.0.1" timeout="123.456000" />

</MyApp>


 

我们如果要修改节点的Connection的ip为192.168.0.100,timeout为1000,我们可以这样用:



    std::string XmlFile = _T("E:\\TestTinyxml\\example4.xml");

    std::string strNodeName = _T("Connection");

   typedef std::pair <std::string,std::string> String_Pair;

   std::map<std::string,std::string> AttMap;

   AttMap.insert(String_Pair(_T("ip"),_T("192.168.0.100")));

   AttMap.insert(String_Pair(_T("timeout"),_T("1000")));

   ModifyNode_Attribute(XmlFile,strNodeName,AttMap);


 

下面是增加节点的两个函数:



/*!

*  \brief 增加指定节点的文本。

*

*  \param XmlFile xml文件全路径。

*  \param strParNodeName 要增加的节点的父节点。

*  \param strNodeName 指定的节点名。

*  \param strText 要增加的文本

*  \return 是否成功。true为成功,false表示失败。

*/

bool AddNode_Text(const std::string& XmlFile,const std::string& strParNodeName,const std::string& strNodeName,const 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,strParNodeName,pNode);


    if (NULL!=pNode)

    {

        // 生成子节点:pNewNode

        TiXmlElement *pNewNode = new TiXmlElement(strNodeName);

        if (NULL==pNewNode)

        {

            return false;

        }

        // 设置节点文本,然后插入节点

        TiXmlText *pNewValue = new TiXmlText(strText);

        pNewNode->LinkEndChild(pNewValue);


        pNode->InsertEndChild(*pNewNode);

        pDoc->SaveFile(XmlFile);

        return true;

    }

    else

         return false;

    

}


/*!

*  \brief 增加节点。

*

*  \param XmlFile xml文件全路径。

*  \param strParNodeName 要增加的节点的父节点。

*  \param strNodeName 指定的节点名。

*  \param AttMap 要增加的节点设定的属性值,这是一个map,前一个为属性名,后一个为属性值

*  \return 是否成功。true为成功,false表示失败。

*/

bool AddNode_Attribute(const std::string& XmlFile,const std::string& strParNodeName,const std::string strNodeName,const std::map<std::string,std::string> &AttMap)

{

    // 定义一个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,strParNodeName,pNode);


    if (NULL!=pNode)

    {

        // 生成子节点:pNewNode

        TiXmlElement *pNewNode = new TiXmlElement(strNodeName);

        if (NULL==pNewNode)

        {

            return false;

        }

        // 设置节点的属性值,然后插入节点

        std::map<std::string,std::string>::const_iterator iter;

        for (iter=AttMap.begin();iter!=AttMap.end();iter++)

        {

             pNewNode->SetAttribute(iter->first,iter->second);

        }


        pNode->InsertEndChild(*pNewNode);

        pDoc->SaveFile(XmlFile);

        return true;

    }

    else

        return false;

}