就TinyXml使用答复一位网友
2010-03-15 23:57
344 查看
作者:朱金灿
来源:http://blog.csdn.net/clever101
一位网友说看了我的TinyXml快速入门系列文章。在修改节点属性值函数ModifyNode_Attribute这个函数的用法参照我的例子运行了下,
<Connection ip="192.168.0.1" timeout="123.456000"/> 如果只有这一个节点的时候是修改正确的,但是如果再加上几个相同名字的节点呢?就像下面一样:
<Connection ip="192.168.0.1" timeout="123.456000"/>
<Connection ip="192.168.0.2" timeout="123.456001"/>
<Connection ip="192.168.0.3" timeout="123.456002"/>
现在他想修改的是<Connection ip="192.168.0.3" timeout="123.456002"/> 这行为<Connection ip="192.168.0.4" timeout="123.456003"/>
请问该如何修改?
鉴于他所提问题有一定代表性,我就再写一篇以作答复。在《TinyXml快速入门(二)》中我提到了无论查询节点、删除节点、修改节点和增加节点,其实都离不开一个函数,就是根据节点名获取相关节点指针,其中一个关键的函数:
具体到这位网友的问题,其实就是增加了一个判断条件,就是要求所求节点不但要求节点名为Connection,还有属性ip的值为192.168.0.3。那么我们可以对GetNodePointerByName函数稍作修改:
然后再增加一个修改属性的函数:
如果要将
<Connection ip="192.168.0.1" timeout="123.456000"/>
<Connection ip="192.168.0.2" timeout="123.456001"/>
<Connection ip="192.168.0.3" timeout="123.456002"/>
中的<Connection ip="192.168.0.3" timeout="123.456002"/> 这行修改为<Connection ip="192.168.0.4" timeout="123.456003"/>
那么测试代码就如下:
来源:http://blog.csdn.net/clever101
一位网友说看了我的TinyXml快速入门系列文章。在修改节点属性值函数ModifyNode_Attribute这个函数的用法参照我的例子运行了下,
<Connection ip="192.168.0.1" timeout="123.456000"/> 如果只有这一个节点的时候是修改正确的,但是如果再加上几个相同名字的节点呢?就像下面一样:
<Connection ip="192.168.0.1" timeout="123.456000"/>
<Connection ip="192.168.0.2" timeout="123.456001"/>
<Connection ip="192.168.0.3" timeout="123.456002"/>
现在他想修改的是<Connection ip="192.168.0.3" timeout="123.456002"/> 这行为<Connection ip="192.168.0.4" timeout="123.456003"/>
请问该如何修改?
鉴于他所提问题有一定代表性,我就再写一篇以作答复。在《TinyXml快速入门(二)》中我提到了无论查询节点、删除节点、修改节点和增加节点,其实都离不开一个函数,就是根据节点名获取相关节点指针,其中一个关键的函数:
/*! * /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; }
具体到这位网友的问题,其实就是增加了一个判断条件,就是要求所求节点不但要求节点名为Connection,还有属性ip的值为192.168.0.3。那么我们可以对GetNodePointerByName函数稍作修改:
/*! * /brief 通过根节点和节点名以及节点的一个属性值获取节点指针。 * * /param pRootEle xml文件的根节点。 * /param strNodeName 要查询的节点名 * /param strNodeName 要查询的节点的一个属性值 * /param Node 需要查询的节点指针 * /return 是否找到。true为找到相应节点指针,false表示没有找到相应节点指针。 */ bool GetNodePointerByName_Attribute(TiXmlElement* pRootEle, std::string &strNodeName, std::string &strAttributeValue, TiXmlElement* &Node) { assert(NULL!=pRootEle); // 假如等于根节点名,就退出 if (strNodeName==pRootEle->Value()) { TiXmlAttribute* pAttr = NULL; for (pAttr = pRootEle->FirstAttribute(); pAttr; pAttr = pAttr->Next()) { std::string strAttValue = pAttr->Value(); if (strAttributeValue==strAttValue) { Node = pRootEle; } } } TiXmlElement* pEle = pRootEle; for (pEle = pRootEle->FirstChildElement(); pEle; pEle = pEle->NextSiblingElement()) { //递归处理子节点 if(GetNodePointerByName_Attribute(pEle,strNodeName,strAttributeValue,Node)) return true; } return false; }
然后再增加一个修改属性的函数:
/*! * /brief 修改指定节点的属性。 * * /param XmlFile xml文件全路径。 * /param strNodeName 指定的节点名。 * /param strAttValue 指定的节点的其中一个属性值。 * /param AttMap 重新设定的属性值,这是一个map,前一个为属性名,后一个为属性值 * /return 是否成功。true为成功,false表示失败。 */ bool ModifyNode_Attribute2(std::string XmlFile,std::string strNodeName, std::string strAttValue, 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_Attribute(pRootEle,strNodeName,strAttValue,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>::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; } }
如果要将
<Connection ip="192.168.0.1" timeout="123.456000"/>
<Connection ip="192.168.0.2" timeout="123.456001"/>
<Connection ip="192.168.0.3" timeout="123.456002"/>
中的<Connection ip="192.168.0.3" timeout="123.456002"/> 这行修改为<Connection ip="192.168.0.4" timeout="123.456003"/>
那么测试代码就如下:
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.4"))); AttMap.insert(String_Pair(_T("timeout"),_T("123.456003"))); ModifyNode_Attribute2(XmlFile,strNodeName,strAttValue,AttMap);
相关文章推荐
- 就TinyXml使用答复一位网友
- 就TinyXml使用答复一位网友
- C++之TinyXML的使用介绍
- tinyxml使用指导
- tinyxml的使用和字符编码转换
- Tinyxml的使用
- 有关TinyXML使用的简单总结
- VS中使用TinyXml操作xml文件
- tinyxml 使用说明http://blog.csdn.net/zww0815/article/details/8083550
- 有关TinyXML使用的简单总结
- TinyXML使用
- C++之tinyXML使用
- C++之tinyXML使用
- cocos2d-x使用libjson和tinyxml解析json和xml的代码示例
- (转)有关TinyXML使用的简单总结
- tinyxml使用笔记与总结
- (转载)C++之tinyXML使用
- VS中使用TinyXml操作xml文件
- 有关TinyXML使用的简单总结:来解析XML数据
- tinyxml使用笔记与总结