参考:http://blog.csdn.net/zww0815/article/details/8083550

  1. // 读者对象:对TinyXml有一定了解的人。本文是对TinyXml工具的一些知识点的理解。
  2. // 1 TinyXml中对TiXmlNode进行了分类,是用一个枚举进行描述的。
  3. // enum NodeType
  4. // {
  5. // DOCUMENT, 文档节点
  6. // ELEMENT, 元素节点
  7. // COMMENT, 还没弄清楚
  8. // UNKNOWN, 未知节点
  9. // TEXT, 文本节点
  10. // DECLARATION, 声明节点
  11. // TYPECOUNT 还没弄清楚
  12. // };
  13. // TiXmlNode * pNode->Type() 函数可以返回节点的类型。
  14. // 枚举的比较方法:TiXmlText::TEXT == pNode->Type();
  15. //
  16. // 这几个类型非常重要,尤其是在遍历xml时或者查找一个节点时
  17. // 我对节点和元素的理解如下:为了说明问题,我使用下面的xml文档来举例说明
  18. // <?xml version="1.0" encoding="gb2312"?>
  19. // <Persons>
  20. // <person Id="200" Shengao=34 ClassName="计本0508">
  21. // <name>vertor</name>
  22. // <age>20</age>
  23. // <address encode="utf-8">
  24. // <country>中国</country>
  25. // <province>山西</province>
  26. // <village>王大庄</village>
  27. // </address>
  28. // </person>
  29. // </Persons>
  30. //
  31. // 2.1 节点:一种对文档结构的描述对象
  32. // 2.2 元素:对文档某一个数据块的描述
  33. // 2.3 文本是指没有孩子的节点
  34. // 例如<village>大王庄</village> 文本节点是:"大王庄"
  35. // 然而判断一个节点是否是文本节点时并不是根据pNode->NoChildren()来判断,而是根据节点的类型来判断
  36. // 因为如果一个节点形如:<village></village>它也是没有孩子节点的。
  37. // 2.4 节点类可以转换成元素对象。
  38. // 例如 TiXmlElement * pElement = pNode->ToElement();
  39. // 那什么时候需要转换成元素呢?
  40. // 当你需要元素的一些属性值是就需要转换了。
  41. // 2.5 元素跟节点都有关于访问孩子的函数,
  42. // 元素访问孩子的函数:
  43. // FirstChildElement() 返回当前元素的孩子元素
  44. // NextSiblingElement() 返回当前元素的同级元素
  45. // 节点访问节点孩子的函数:
  46. // FirstChild() 返回当前节点的孩子节点
  47. // NextSibing() 返回当前节点的同级下一个节点
  48. // 个人觉得 元素访问和节点访问在一般的访问下没有区别,两者都可以访问的孩子
  49. // 对于一些特殊的情况下才需要区分。比如你要访问属性时,就需要用元素来找到第一个属性值。
  50. // 2.6 对于遍历一个xml文档时,思路一般是这样的:
  51. // 1 载入一个xml
  52. // 2 获得根元素(不是根节点)
  53. // 3 循环访问每一个根元素的子元素
  54. // 4 对每一个子元素进行解析。
  55. // 4.1 获取子元素的类型Type
  56. // 4.2 switch(Type)
  57. // case TEXT:
  58. // 输出文本节点的值pNode->value()
  59. // case ELEMENT:
  60. // 获取元素的value(这里的value指的是元素的名字,例如:person元素)
  61. // 循环获取元素的每一个属性
  62. // a 得到元素的第一个属性
  63. // b do——while循环获取每一个属性和值。
  64. // case COMMENT: 暂时不用管
  65. // case UNKNOWN: 暂时不用管
  66. // case DECLARATION:
  67. // 获取元素的版本,编码方式等等
  68. // 4.3 循环遍历子元素的下一级元素(即孙子元素) 在这里也可以遍历孙子节点。
  69. // 递归调用第四步。
  70. // 基本思路就是这样,具体代码见后面
  71. // 2.7 如果定位一个节点
  72. // 唯一确定一个节点的方法是根据节点名,属性名,属性值
  73. // 1 根据xml的遍历思想找到与给定节点名一样的节点
  74. // 2 如果这个节点有属性并且属性名和值与给定的一致,说明找到了。
  75. // 3 如果没有一致的,说明解析失败。
  76. // 4 如果没有给定属性名和值,则可以默认只查找与节点名一致的节点。
  77. // 2.8 编码问题
  78. // 用TinyXml加载一个xml文档时,根据文档的编码方式来加载,在操作过程中需要进行编码转换
  79. // 如果encoding=utf-8 则在遍历时,需要进行编码转换,具体转换还没找到方法。
  80. //
  81. // 2.9 指针的 new和释放。
  82. // TinyXml已经帮我们把指针分配的内存进行了管理,在析构函数中进行了处理,我们不需要处理new出来的指针
  83. // 如果我们显示的delete时,有可能影响程序运行。
  84. // 3.0 对于添加一个节点,删除一个节点,更新一个节点时,都需要在最后SaveFile,我就好几次忘了SaveFile,所以调了老半天。
  85. // 3.1 总的来说,Tinyxml还是不错的,以后继续学习。
  86. // 部分功能代码
  87. // 3.2 对于插入一个节点,首先获取要插入节点的父节点,然后进行插入,最需要注意的是在查询父节点的是时候,必须对应同一个文本对象来操作。有可能在两个函数中同时打开了同一个xml文档,虽然名字一样,但是不是同一个xmldocument对象,所以操作会失败。
  88. // 最后要保存。
  89.  
  90. #include "XmlTest.h"
  91.  
  92. #define MAX_NUM 256
  93.  
  94. /************************************************************************/
  95. /* 创建一个xml文档 */
  96. /************************************************************************/
  97. void createXml(const char * ccXmlName)
  98. {
  99.  
  100. //创建一个XML的文档对象。
  101. TiXmlDocument *myDocument = new TiXmlDocument();
  102. TiXmlDeclaration* decl = new TiXmlDeclaration("1.0","gb2312","yes");
  103. myDocument->LinkEndChild(decl);
  104.  
  105. //创建一个根元素并连接。
  106. TiXmlElement *RootElement = new TiXmlElement("Persons");
  107. myDocument->LinkEndChild(RootElement);
  108.  
  109. for(int i=; i<;i++)
  110. {
  111. //创建一个Person元素并连接。
  112. TiXmlElement *PersonElement = new TiXmlElement("Person");
  113. RootElement->LinkEndChild(PersonElement);
  114.  
  115. //设置Person元素的属性。
  116. PersonElement->SetAttribute("ID", i);
  117.  
  118. //创建name元素、age元素并连接。
  119. TiXmlElement *NameElement = new TiXmlElement("name");
  120. TiXmlElement *AgeElement = new TiXmlElement("age");
  121. PersonElement->LinkEndChild(NameElement);
  122. PersonElement->LinkEndChild(AgeElement);
  123.  
  124. //设置name元素和age元素的内容并连接。
  125. TiXmlText *NameContent = new TiXmlText("周星星");
  126. TiXmlText *AgeContent = new TiXmlText("");
  127. NameElement->LinkEndChild(NameContent);
  128. AgeElement->LinkEndChild(AgeContent);
  129.  
  130. }
  131.  
  132. //保存到文件
  133. myDocument->SaveFile(ccXmlName);
  134. }
  135.  
  136. /************************************************************************/
  137. /* 遍历一个xml文档 */
  138. /************************************************************************/
  139. void readXml(const char * ccXmlName)
  140. {
  141. //创建一个XML的文档对象。
  142. TiXmlDocument *myDocument = new TiXmlDocument(ccXmlName);
  143. myDocument->LoadFile();
  144.  
  145. //获得xml的头,即声明部分
  146. TiXmlDeclaration* decl = myDocument->FirstChild()->ToDeclaration();
  147. cout << "xml文件的版本是:" << decl->Version() << endl;
  148. cout << "xml的编码格式是:" << decl->Encoding() << endl;
  149.  
  150. //获得根元素
  151. TiXmlElement *RootElement = myDocument->RootElement();
  152.  
  153. //输出根元素名称
  154. cout << RootElement->Value() << endl;
  155.  
  156. TiXmlNode* pNode = NULL;
  157. string msg = "";
  158.  
  159. for(pNode=RootElement->FirstChildElement();pNode;pNode=pNode->NextSiblingElement())
  160. {
  161. msg += dumpNode(pNode,);
  162. }
  163.  
  164. cout << msg << endl;
  165. }
  166.  
  167. /************************************************************************/
  168. /*描述:遍历一个元素
  169. 时间:2012-9-18
  170. 参数说明:pNode节点,flag 节点嵌套层数
  171. /************************************************************************/
  172. string dumpNode(TiXmlNode * pNode,int flag)
  173. {
  174. string msg = "";
  175.  
  176. if(pNode == NULL)
  177. {
  178. return "";
  179. }
  180.  
  181. TiXmlText * pText = NULL;
  182. TiXmlNode * pChildNode = NULL;
  183. int t = pNode->Type();
  184.  
  185. switch(t)
  186. {
  187. //节点类型是text节点
  188. case TiXmlText::TINYXML_TEXT:
  189. { pText = pNode->ToText();
  190. string text = pText->Value();
  191. if(!text.empty())
  192. {
  193. msg = msg + "="+ text;
  194. }
  195. break;
  196. }
  197.  
  198. //节点类型是Element
  199. case TiXmlText::TINYXML_ELEMENT:
  200. {
  201. msg = msg + "\r\n";
  202. int num = flag;
  203.  
  204. while(num >= )
  205. {
  206. msg = msg + " ";
  207. num--;
  208. }
  209.  
  210. msg = msg + pNode->Value();
  211.  
  212. //输出属性
  213. TiXmlElement * pElement = pNode->ToElement();
  214.  
  215. TiXmlAttribute * pAttr = pElement->FirstAttribute();
  216. TiXmlAttribute * pNextAttr =NULL;
  217. string tmpAttrMsg = "[";
  218.  
  219. //if(pAttr != NULL && !(string(pAttr->Name())).compare("name") && !(string(pAttr->Value())).compare("IDH_CFG_USB"))
  220. if(pAttr != NULL )
  221. {
  222. string tmpAttrVal = "";
  223. string tmpAttrName = "";
  224.  
  225. do
  226. {
  227. tmpAttrVal = pAttr->Value();
  228. tmpAttrName = pAttr->Name();
  229. tmpAttrMsg += tmpAttrName + "=" +tmpAttrVal + ","; //各个属性之间用逗号分隔
  230. }while(pAttr = pAttr->Next());
  231.  
  232. /* 去掉最后的',' */
  233. tmpAttrMsg = tmpAttrMsg.erase(tmpAttrMsg.find_last_of(","));
  234. //同上 tmpAttrMsg = tmpAttrMsg.substr(0,tmpAttrMsg.find_last_of(","));
  235.  
  236. }
  237. tmpAttrMsg += "]";
  238. msg += tmpAttrMsg;
  239.  
  240. break;
  241. }
  242.  
  243. case TiXmlText::TINYXML_DOCUMENT:
  244. case TiXmlText::TINYXML_COMMENT:
  245. case TiXmlText::TINYXML_UNKNOWN:
  246. case TiXmlText::TINYXML_DECLARATION:
  247. case TiXmlText::TINYXML_TYPECOUNT:
  248. {
  249. ;//Nothing to do
  250. }
  251. }
  252.  
  253. //循环访问它的每一个元素
  254. for(pChildNode=pNode->FirstChild();pChildNode!=;pChildNode = pChildNode->NextSibling())
  255. {
  256.  
  257. msg = msg + dumpNode(pChildNode,flag+);
  258.  
  259. }
  260.  
  261. return msg;
  262. }
  263.  
  264. /************************************************************************/
  265. /* 查询出唯一节点 */
  266. /* 参数说明:
  267. string nodeName 节点名
  268. string nodeAttrName 节点的属性
  269. string nodeAttrValue 节点属性的值
  270. /************************************************************************/
  271. TiXmlNode * SelectSingleNode(const char * cXmlName,string nodeName,string nodeAttrName,string nodeAttrValue)
  272. {
  273. //加载一个XML的文档对象。
  274.  
  275. TiXmlDocument *xmlDoc = new TiXmlDocument(cXmlName);
  276. if(!xmlDoc->LoadFile()) //是tinyXml会自动处理文档的BOM
  277. {
  278. return NULL;
  279. }
  280.  
  281. if(xmlDoc == NULL)
  282. {
  283. return NULL;
  284. }
  285.  
  286. //获得根元素
  287. TiXmlElement *RootElement = xmlDoc->RootElement();
  288. if(RootElement == NULL)
  289. {
  290. cout << "解析错误,无法获取根元素" << endl;
  291. return NULL;
  292. }
  293.  
  294. TiXmlNode * pNode = NULL;
  295. TiXmlNode * pSelectNode = NULL;
  296. string msg = "";
  297.  
  298. for(pNode=RootElement->FirstChildElement();pNode;pNode=pNode->NextSiblingElement())
  299. {
  300.  
  301. pSelectNode = selectChildNode(pNode,nodeName,nodeAttrName,nodeAttrValue);
  302. if(pSelectNode)
  303. {
  304. break;
  305. }
  306. }
  307.  
  308. if(pSelectNode)
  309. {
  310. cout << "解析成功" << endl;
  311. cout << "[节点名]=" << pSelectNode->Value() << endl;
  312. return pSelectNode;
  313. }
  314. else
  315. {
  316. cout << "解析错误,无法获取节点" << endl;
  317. return NULL;
  318. }
  319.  
  320. }
  321.  
  322. TiXmlNode * SelectSingleNodeByRootEle(TiXmlElement* RootElement,string nodeName,string nodeAttrName,string nodeAttrValue)
  323. {
  324. //加载一个XML的文档对象。
  325.  
  326. // TiXmlDocument *xmlDoc = new TiXmlDocument(cXmlName);
  327. // if(!xmlDoc->LoadFile()) //是tinyXml会自动处理文档的BOM
  328. // {
  329. // return NULL;
  330. // }
  331. //
  332. //
  333. // if(xmlDoc == NULL)
  334. // {
  335. // return NULL;
  336. // }
  337.  
  338. //获得根元素
  339. //TiXmlElement *RootElement = xmlDoc->RootElement();
  340. if(RootElement == NULL)
  341. {
  342. cout << "解析错误,无法获取根元素" << endl;
  343. return NULL;
  344. }
  345.  
  346. TiXmlNode * pNode = NULL;
  347. TiXmlNode * pSelectNode = NULL;
  348. string msg = "";
  349.  
  350. for(pNode=RootElement->FirstChildElement();pNode;pNode=pNode->NextSiblingElement())
  351. {
  352.  
  353. pSelectNode = selectChildNode(pNode,nodeName,nodeAttrName,nodeAttrValue);
  354. if(pSelectNode)
  355. {
  356. break;
  357. }
  358. }
  359.  
  360. if(pSelectNode)
  361. {
  362. //cout << "解析成功" << endl;
  363. //cout << pSelectNode->Value() << endl;
  364. return pSelectNode;
  365. }
  366. else
  367. {
  368. cout << "解析错误,无法获取节点" << endl;
  369. return NULL;
  370. }
  371.  
  372. }
  373.  
  374. /************************************************************************/
  375. /*
  376. 根据父节点循环遍历查找子节点
  377. 参数说明
  378. noteName 节点名
  379. noteAttrName 属性名
  380. noteAttrValue 属性值
  381. /************************************************************************/
  382. TiXmlNode * selectChildNode(TiXmlNode * pNode,string nodeName,string nodeAttrName,string nodeAttrValue)
  383. {
  384. if(pNode == NULL)
  385. {
  386. return NULL;
  387. }
  388. TiXmlNode * pSelectedNode = NULL;
  389. TiXmlNode * pChildNode = NULL;
  390. int t = pNode->Type();
  391. switch (t)
  392. {
  393. case TiXmlText::TINYXML_DOCUMENT:
  394. case TiXmlText::TINYXML_DECLARATION:
  395. case TiXmlText::TINYXML_TEXT:
  396. case TiXmlText::TINYXML_UNKNOWN:
  397. case TiXmlText::TINYXML_COMMENT:
  398. break;
  399. case TiXmlText::TINYXML_ELEMENT:
  400. if(pNode->Value() == nodeName)
  401. {
  402. //cout << pNode->Value() << endl;
  403. if(!nodeAttrName.empty() && !nodeAttrValue.empty())
  404. {
  405. TiXmlElement * pElement = pNode->ToElement();
  406.  
  407. TiXmlAttribute * pAttr = pElement->FirstAttribute();
  408. TiXmlAttribute * pNextAttr =NULL;
  409. if(pAttr != NULL)
  410. {
  411. do
  412. {
  413. if(pAttr->Name()==nodeAttrName&&pAttr->Value()== nodeAttrValue)
  414. {
  415. //cout << pAttr->Value() << endl;
  416. return pNode;
  417. }
  418. }while(pAttr = pAttr->Next());
  419. }
  420. }
  421. else
  422. {
  423. return pNode;
  424. }
  425.  
  426. }
  427. else
  428. {
  429. //循环访问它的每一个元素
  430. for(pChildNode=pNode->FirstChild();
  431. pChildNode!=;
  432. pChildNode = pChildNode->NextSibling())
  433. {
  434. pSelectedNode = selectChildNode(
  435. pChildNode,
  436. nodeName,
  437. nodeAttrName,
  438. nodeAttrValue);
  439. if(pSelectedNode)
  440. {
  441. return pSelectedNode;
  442. }
  443. }
  444. }
  445.  
  446. default:break;
  447. }
  448. return NULL;
  449. }
  450.  
  451. /************************************************************************/
  452. /* 普通插入一个节点,还不完善。 */
  453. /************************************************************************/
  454. bool insert(const char * ccXmlName)
  455. {
  456. //加载一个XML的文档对象。
  457. TiXmlDocument *myDocument = new TiXmlDocument(ccXmlName);
  458. myDocument->LoadFile();
  459.  
  460. if(myDocument == NULL)
  461. {
  462. return false;
  463. }
  464. //获得xml的头,即声明部分
  465. TiXmlDeclaration* decl = myDocument->FirstChild()->ToDeclaration();
  466. if(decl != NULL)
  467. {
  468. cout << "xml文件的版本是:" << decl->Version() << endl;
  469. cout << "xml的编码格式是:" << decl->Encoding() << endl;
  470. }
  471.  
  472. //获得根元素
  473. TiXmlElement *RootElement = myDocument->RootElement();
  474.  
  475. if(RootElement != NULL)
  476. {
  477.  
  478. //创建一个Person元素并连接。
  479. TiXmlElement *PersonElement = new TiXmlElement("Person");
  480. PersonElement->SetAttribute("Id",);
  481. RootElement->LinkEndChild(PersonElement);
  482.  
  483. TiXmlText *textElement = new TiXmlText("Jam");
  484. PersonElement->LinkEndChild(textElement);
  485.  
  486. //增加一个team元素
  487. TiXmlElement *TeamElement = new TiXmlElement("team");
  488. TeamElement->SetAttribute("TID","");
  489. RootElement->LinkEndChild(TeamElement);
  490.  
  491. //增加team的子节点name
  492. TiXmlElement *teamName = new TiXmlElement("name");
  493. TiXmlText *nameText = new TiXmlText("workgroup");
  494. teamName->LinkEndChild(nameText);
  495. TeamElement->LinkEndChild(teamName);
  496.  
  497. //增加team的子节点type
  498. TiXmlElement *teamType = new TiXmlElement("type");
  499. TiXmlText *typeText = new TiXmlText("SI");
  500. teamType->LinkEndChild(typeText);
  501.  
  502. TeamElement->LinkEndChild(teamType);
  503.  
  504. myDocument->SaveFile("Person.xml");
  505.  
  506. //输出根元素名称
  507. cout << RootElement->Value() << endl;
  508. return true;
  509. }
  510. return false;
  511. }
  512.  
  513. /************************************************************************/
  514. /* 获取一个节点的属性 */
  515. /************************************************************************/
  516. string getAttribute(TiXmlNode * pNode)
  517. {
  518. if(pNode == NULL) return "";
  519. //输出属性
  520. string msg = "";
  521. TiXmlElement * pElement = pNode->ToElement();
  522.  
  523. TiXmlAttribute * pAttr = pElement->FirstAttribute();
  524. TiXmlAttribute * pNextAttr =NULL;
  525. string tmpAttrMsg = "";
  526.  
  527. if(pAttr != NULL)
  528. {
  529. string tmpAttrVal = "";
  530. string tmpAttrName = "";
  531.  
  532. do
  533. {
  534. tmpAttrVal = pAttr->Value();
  535. tmpAttrName = pAttr->Name();
  536. tmpAttrMsg += "[" + tmpAttrName + "]=" + tmpAttrVal+"\n"; //各个属性之间用逗号分隔
  537. }while(pAttr = pAttr->Next());
  538.  
  539. //tmpAttrMsg = tmpAttrMsg.erase(tmpAttrMsg.find_last_of(","));
  540. }
  541.  
  542. //tmpAttrMsg += "]";
  543. msg += tmpAttrMsg;
  544.  
  545. return msg;
  546. }
  547.  
  548. /************************************************************************/
  549. /* 在指定位置插入一个元素 */
  550. /************************************************************************/
  551. bool insertAElement(const char * cXmlName, TiXmlElement * pElement)
  552. {
  553. //加载一个XML的文档对象。
  554. TiXmlDocument *xmlDoc = new TiXmlDocument(cXmlName);
  555. xmlDoc->LoadFile();
  556.  
  557. if(xmlDoc == NULL)
  558. {
  559. return false;
  560. }
  561.  
  562. //获得xml的头,即声明部分
  563. TiXmlDeclaration* decl = xmlDoc->FirstChild()->ToDeclaration();
  564. if(decl != NULL)
  565. {
  566. cout << "xml文件的版本是:" << decl->Version() << endl;
  567. cout << "xml的编码格式是:" << decl->Encoding() << endl;
  568. }
  569. //获得根元素
  570. TiXmlElement *RootElement = xmlDoc->RootElement();
  571. if(RootElement != NULL)
  572. {
  573. TiXmlNode * pNode = SelectSingleNode(cXmlName,"name","length","");
  574. if(pNode == NULL)
  575. {
  576. return false;
  577. }
  578.  
  579. //创建一个Person元素并连接。
  580. TiXmlElement *pNewElement = new TiXmlElement("Person");
  581. if(pNewElement == NULL)
  582. {
  583. return false;
  584. }
  585. pNewElement->SetAttribute("Id","");
  586. TiXmlText *textElement = new TiXmlText("gbnn");
  587. if(textElement == NULL)
  588. {
  589. return false;
  590. }
  591. pNewElement->LinkEndChild(textElement);
  592. TiXmlNode * pRet = pNode->InsertBeforeChild(pNode->LastChild(),*pNewElement);
  593. //TiXmlNode * pRet = pNode->LinkEndChild(pNewElement);
  594. xmlDoc->Print();
  595. bool b = xmlDoc->SaveFile();
  596. if(b)
  597. {
  598. cout << "添加成功" << endl;
  599. return b;
  600. }
  601. else
  602. {
  603. cout << "添加失败" << endl;
  604. return false;
  605. }
  606. }
  607. else
  608. {
  609. return false;
  610. }
  611. }
  612.  
  613. //const char * cXmlName,string strNodeName,string strNodeAttrName,string strNdeAttrValue,string strPath
  614. /*!
  615. * \Function: 修改一个唯一节点中第二、三属性的值为一子符串
  616. *
  617. * \param cXmlName xml文件名
  618. * \param strNodeName 指定的节点名。
  619. * \param strNodeAttrName 指定的节点名所在节点中第一属性名。
  620. * \param strNdeAttrValue 指定的节点名所在节点中第一属性值。
  621. * \param strPath 字符串。为当前路径名的上一级目录的字符串
  622. * \return 是否成功。true为成功,false表示失败。
  623. */
  624. bool ModifySingleNode(const char * cXmlName,string strNodeName,string strNodeAttrName,string strNdeAttrValue,string strPath)
  625. {
  626. if (strNodeName.empty() || strNodeAttrName.empty() || strNdeAttrValue.empty() ||strPath.empty())
  627. {
  628. return false;
  629. }
  630.  
  631. // 定义一个TiXmlDocument类指针
  632. TiXmlDocument *pDoc = new TiXmlDocument();
  633. if (NULL==pDoc)
  634. {
  635. return false;
  636. }
  637.  
  638. pDoc->LoadFile(cXmlName);
  639.  
  640. TiXmlElement* pRootElement = pDoc->RootElement();
  641.  
  642. TiXmlNode * pNode = SelectSingleNodeByRootEle(pRootElement,strNodeName,strNodeAttrName,strNdeAttrValue);
  643.  
  644. if (NULL == pNode)
  645. {
  646. return false;
  647. }
  648.  
  649. //输出属性
  650. TiXmlElement * pElement = pNode->ToElement();
  651.  
  652. TiXmlAttribute * pAttr = pElement->FirstAttribute();
  653. TiXmlAttribute * pNextAttr =NULL;
  654.  
  655. if(pAttr != NULL)
  656. {
  657. string tmpAttrVal = "";
  658. string tmpAttrName = "";
  659.  
  660. do
  661. {
  662. tmpAttrVal = pAttr->Value();
  663. tmpAttrName = pAttr->Name();
  664.  
  665. //节点中第一个属性对跳过
  666. if (tmpAttrName == strNodeAttrName && tmpAttrVal == strNdeAttrValue)
  667. {
  668. continue;
  669. }
  670.  
  671. //修改第二和第三个属性对
  672. if ("href" == tmpAttrName)
  673. {
  674. pAttr->SetValue(strPath.c_str());
  675. }
  676.  
  677. if ("test" == tmpAttrName)
  678. {
  679. pAttr->SetValue(strPath.c_str());
  680. }
  681.  
  682. }while(pAttr = pAttr->Next());
  683. }
  684.  
  685. pDoc->SaveFile("hhhhhhhhhhhhh.xml");
  686.  
  687. return true;
  688. }
  689.  
  690. void ShowSingleNode(const char * cXmlName,string strNodeName,string strNodeAttrName,string strNdeAttrValue)
  691. {
  692. TiXmlNode * pNode = SelectSingleNode(cXmlName,strNodeName,strNodeAttrName,strNdeAttrValue);
  693.  
  694. if (NULL == pNode)
  695. {
  696. return;
  697. }
  698.  
  699. string strTem = getAttribute(pNode);
  700.  
  701. cout << strTem.c_str() << endl;
  702. }
  703.  
  704. string PathOpt()
  705. {
  706. char cStr[MAX_NUM];
  707. GetCurrentDirectory(MAX_NUM,cStr);
  708.  
  709. string str = cStr;
  710.  
  711. //取当前路径的上一目录所在路径
  712. size_t pos = str.find_last_of("\\");
  713. str.erase(str.begin()+pos,str.end());
  714.  
  715. return str;
  716. }
  717.  
  718. int main()
  719. {
  720. const char * cXmlName = "files.xml";
  721. string strPath;
  722. //createXml(ccXmlName);
  723. //readXml(cXmlName);
  724. //insert(ccXmlName);
  725. //readXml(ccXmlName);
  726.  
  727. ShowSingleNode(cXmlName,"Document","title","About VMware Player Help");
  728.  
  729. strPath = PathOpt();
  730.  
  731. bool ret = ModifySingleNode(cXmlName,"Document","title","About VMware Player Help",strPath);
  732.  
  733. if (ret)
  734. {
  735. cout << "OK" << endl;
  736. }
  737. else
  738. {
  739. cout << "false" << endl;
  740. }
  741.  
  742. ShowSingleNode("hhhhhhhhhhhhh.xml","Document","title","About VMware Player Help");
  743. return ;
  744. }

自己改写的代码

  1. TiXmlElement* m_pCurElement; ///< 当前元素
  1. /** @brief 设置当前位置到特定的节点 */
  1. bool SetToSelectNode(TiXmlNode * pNode, const std::string& szName, const std::string& szAttribute, const std::string& szValue)
  2. {
  3. if(pNode == NULL)
  4. {
  5. return false;
  6. }
  7. if(pNode->Value() == szName)
  8. {
  9. //找到了相同的节点名称
  10. if(!szAttribute.empty() && !szValue.empty())
  11. {
  12. // 循环获取元素的每一个属性
  13. // a 得到元素的第一个属性
  14. // b do——while循环获取每一个属性和值。
  15. TiXmlElement * pElement = pNode->ToElement();
  16.  
  17. TiXmlAttribute * pAttr = pElement->FirstAttribute();
  18. TiXmlAttribute * pNextAttr =NULL;
  19. if(pAttr != NULL)
  20. {
  21. do
  22. {
  23. if(pAttr->Name()==szAttribute&&pAttr->Value()== szValue)
  24. {
  25. m_pCurElement = pElement;
  26. return true;
  27. }
  28. }while(pAttr = pAttr->Next());
  29. }
  30. }
  31. else
  32. {
  33. //如果 nodeAttrName 或者 nodeAttrValue 不需要找,则直接选取此点。
  34. m_pCurElement = pNode->ToElement();
  35. return true;
  36. }
  37.  
  38. }
  39. else
  40. {
  41. //循环访问它的每一个元素
  42. for(TiXmlNode *pChildNode =pNode->FirstChild(); pChildNode!=; pChildNode = pChildNode->NextSibling())
  43. {
  44. if(SetToSelectNode(pChildNode,szName, szAttribute,szValue))
  45. {
  46. return true;
  47. }
  48. }
  49. }
  50. return false;
  51. }

TinyXml节点查找及修改的更多相关文章

  1. Dom4j 操作, 节点查找 添加 删除 修改 。。。xPath

    转: Dom4j 操作, 节点查找 添加 删除 修改 ...xPath 2013年11月28日 10:48:59 今晚打酱油8 阅读数:8506更多 个人分类: JavaWeb   版权声明:本文为博 ...

  2. jackson中JSON字符串节点遍历和修改

    有些场景下,在实现一些基础服务和拦截器的时候,我们可能需要在不知道JSON字符串所属对象类型的情况下,对JSON字符串中的某些属性进行遍历和修改,比如,设置或查询一些报文头字段. 在jackson中, ...

  3. JQuery学习笔记(3)——节点操作 节点查找

    插入节点 内部插入 所谓的内部插入,就是指在节点里面的插入,而外部插入,则是在节点外面插入. append() prepend() appendTo() prependTo() append和prep ...

  4. iOS --SQL的增加、删除、查找、修改

    iOS对于数据库的操作:增加.删除.查找.修改 首先需要创建一个数据库:本程序的数据库是在火狐浏览器里的插件里写的微量型数据库 火狐找查找SQLite Manager的步骤: 第一步:在工具栏找到附加 ...

  5. jQuery的父,子,兄弟节点查找方法

    以下罗列一下jQery下节点查找的方法: jQuery.parent(expr) 找父亲节点.能够传入expr进行过滤,比方$("span").parent()或者$(" ...

  6. JavaScript---Dom树详解,节点查找方式(直接(id,class,tag),间接(父子,兄弟)),节点操作(增删改查,赋值节点,替换节点,),节点属性操作(增删改查),节点文本的操作(增删改查),事件

    JavaScript---Dom树详解,节点查找方式(直接(id,class,tag),间接(父子,兄弟)),节点操作(增删改查,赋值节点,替换节点,),节点属性操作(增删改查),节点文本的操作(增删 ...

  7. JS操作DOM节点查找

    JS中常用的DOM操作事件,包括有节点查找,键盘鼠标事件等等,本文内容介绍DOM的节点查找. <script> window.onload = function(){ //children ...

  8. 用find命令查找最近修改过的文件

    Linux的终端上,没有windows的搜索那样好用的图形界面工具,但find命令确是很强大的. 比如按名字查找一个文件,可以用 find / -name targetfilename . 唉,如果只 ...

  9. Linux系统下查找最近修改过的文件

    Linux的终端上,没有windows的搜索那样好用的图形界面工具,但find命令确是很强大的. 比如按名字查找一个文件,可以用 find / -name targetfilename . 唉,如果只 ...

随机推荐

  1. jmeter 基础功能详解

    jmeter 基础功能详解 thread group:包含一组线程,每个线程独立地执行测试计划. sampler:采样器,有多种不同的sample实现,用来发起各种请求,如http请求,jdbc请求, ...

  2. Genymotion虚拟镜像下载慢或者失败的解决办法

    Genymotion虚拟镜像下载慢或者失败的解决办法 http://files2.genymotion.com/dists/8.0.0/ova/genymotion_vbox86p_8.0_18061 ...

  3. dedecms开启报错

    php.ini里面设置display_errors = On 开启错误提示,error_reporting = E_ALL & ~E_NOTICE 设置错误等级.也可以在php文件中ini_s ...

  4. 阿里云云主机swap功能设置实战案例

    阿里云云主机swap功能设置实战案例 阿里云提供的云服务器(Elastic Compute Service,简称 ECS),是云主机的一种,当前采用的虚拟化驱动是Xen(这一点可以通过bios ven ...

  5. Maven(一)如何用Eclipse创建一个Maven项目

    1.什么是Maven Apache Maven 是一个项目管理和整合工具.基于工程对象模型(POM)的概念,通过一个中央信息管理模块,Maven 能够管理项目的构建.报告和文档. Maven工程结构和 ...

  6. [转] Python的import初探

    转载自:http://www.lingcc.com/2011/12/15/11902/#sec-1 日常使用python编程时,为了用某个代码模块,通常需要在代码中先import相应的module.那 ...

  7. 浏览器内核、排版引擎、js引擎

    [定义] 浏览器最重要或者说核心的部分是“Rendering Engine”,可大概译为“渲染引擎”,不过我们一般习惯将之称为“浏览器内核”.负责对网页语法的解释(如标准通用标记语 言下的一个应用HT ...

  8. ELK之logstash6.5

    首先安装,这里采用rpm安装: # rpm --import https://artifacts.elastic.co/GPG-KEY-elasticsearch 创建repo文件: [root@no ...

  9. html模板生成静态页面及模板分页处理

    它只让你修改页面的某一部分,当然这"某一部分"是由你来确定的.美工先做好一个页面,然后我们把这个页面当作模板(要注意的是这个模板就没必要使用EditRegion3这样的代码了,这种 ...

  10. Python3基础 hasattr 测试类是否有指定的类属性

             Python : 3.7.0          OS : Ubuntu 18.04.1 LTS         IDE : PyCharm 2018.2.4       Conda ...