使用TinyXML读写xml文件

本文详细介绍TinyXML库的使用方法,包括如何用C++编写和读取XML文件。TinyXML是一款基于DOM模型的XML解析器,适用于存储简单数据、配置文件和对象序列化。文章提供了创建XML文档、节点和文本信息的具体代码示例,以及读取复杂XML文件的步骤和代码实现。

哭

 

1、TinyXML


   引用网上的原话:TinyXML是目前非常流行的一款基于DOM模型的XML解析器,简单易用且小巧 玲珑,非常适合存储简单数据,配置文件,对象序列化等数据量不是很大的操作。支持对XML的读取和修改,不直接支持XPath,需要借助另一个相关的类库TinyXPath才可以支持XPath。

    TinyXML源码是使用C++语言编写的,这对于C++应用来说是很好的XML操作工具了。TinyXML附带的文档中给出了它的类组织形式:




TiXmlDocument : XML文档类,它一般用于指示一个文档对象;

TiXmlDeclaration:  XML标识类,也就是XML文件第一行中标注的相关信息;

 TiXmlElement:    XML节点类,这个类用来表示一个节点;

TiXmlText:      XML节点类的文本信息类,标注了XML节点类的文本信息;

TiXmlComment: XML的注释信息类,用来标识XML文档类的注释信息;

上述的这些类全部组织在如下的几个文件中,在使用这个小巧的工具的时候只需要将这4个.cpp文件和2个.h添加到工程中,非常的方便。




2、使用TinyXML写文件


XML的文件结构一般都如下面这段内容所示,第一行表明的是xml的文件版本,编码方式等重要信息。在我们自己写XML的时候可以不写着一行,但是为了通用性,以及后续的可修改性,最好要加上这些必要的信息,毕竟有些XML操作工具对这些是有严格限定的。

<Persons> abc </Persons> 这一行信息中<></>标记的是一个XML的结点,结点的名称就是在<>中的内容,abc就是这个结点的一个属性了。XML的详细文件结构可以看XML的文件结构说明。


  1. <?xml version="1.0" encoding="UTF-8" ?>  
  2. <Persons>  
  3.     <Person Number="1">  
  4.         <name>sunsusn</name>  
  5.         <price>22.5</price>  
  6.     </Person>  
  7. </Persons>  

 
  1. <?xml version="1.0" encoding="UTF-8" ?>
  2. <Persons>
  3. <Person Number="1">
  4. <name>sunsusn </name>
  5. <price>22.5 </price>
  6. </Person>
  7. </Persons>


 


创建一个工程,然后使用上面介绍过的相关类来创建一个XML文件,并且写入相关信息到XML文档中。


  1. #include <iostream>  
  2. #include <string>  
  3. #include "xml/tinyxml.h"  
  4. #include "xml/tinystr.h"  
  5.   
  6. using namespace std;  
  7.   
  8. int main()  
  9. {  
  10.     string fileName = "test.xml";  
  11.     TiXmlDocument *doc = new TiXmlDocument();               //创建xml文档对象  
  12.       
  13.     TiXmlDeclaration *pDeclaration = new TiXmlDeclaration("1.0","UTF-8","");  
  14.     doc->LinkEndChild(pDeclaration);  
  15.       
  16.     TiXmlElement *RootLv1 = new TiXmlElement("Numbers");    //创建一个根结点  
  17.     doc->LinkEndChild(RootLv1);                              //链接到文档对象下  
  18.       
  19.     TiXmlElement *RootLv2 = new TiXmlElement("number");     //创建一个节点  
  20.     RootLv1->LinkEndChild(RootLv2);                          //链接到节点RootLv1下  
  21.     RootLv2->SetAttribute("Number""1");                    //设置节点RootLv2属性  
  22.       
  23.     TiXmlElement *Name = new TiXmlElement("name");          //创建节点  
  24.     RootLv2->LinkEndChild(Name);                         //链接节点到RootLv2下  
  25.       
  26.     TiXmlElement *Price = new TiXmlElement("price");        //创建节点  
  27.     RootLv2->LinkEndChild(Price);                            //链接节点到RootLv2下  
  28.       
  29.     TiXmlText *NameText = new TiXmlText("Robin");           //创建XmlText文本  
  30.     Name->LinkEndChild(NameText);                            //链接到Name下  
  31.   
  32.     TiXmlText *PriceText = new TiXmlText("22.5");           //创建XmlText  
  33.     Price->LinkEndChild(PriceText);                          //链接到Price下  
  34.        
  35.     doc->SaveFile("c:\\test.xml");                           //保存到文件  
  36.     return 0;  
  37. }  

 
  1. #include <iostream>
  2. #include <string>
  3. #include "xml/tinyxml.h"
  4. #include "xml/tinystr.h"
  5. using namespace std;
  6. int main()
  7. {
  8. string fileName = "test.xml";
  9. TiXmlDocument *doc = new TiXmlDocument(); //创建xml文档对象
  10. TiXmlDeclaration *pDeclaration = new TiXmlDeclaration( "1.0", "UTF-8", "");
  11. doc->LinkEndChild(pDeclaration);
  12. TiXmlElement *RootLv1 = new TiXmlElement( "Numbers"); //创建一个根结点
  13. doc->LinkEndChild(RootLv1); //链接到文档对象下
  14. TiXmlElement *RootLv2 = new TiXmlElement( "number"); //创建一个节点
  15. RootLv1->LinkEndChild(RootLv2); //链接到节点RootLv1下
  16. RootLv2->SetAttribute( "Number", "1"); //设置节点RootLv2属性
  17. TiXmlElement *Name = new TiXmlElement( "name"); //创建节点
  18. RootLv2->LinkEndChild(Name); //链接节点到RootLv2下
  19. TiXmlElement *Price = new TiXmlElement( "price"); //创建节点
  20. RootLv2->LinkEndChild(Price); //链接节点到RootLv2下
  21. TiXmlText *NameText = new TiXmlText( "Robin"); //创建XmlText文本
  22. Name->LinkEndChild(NameText); //链接到Name下
  23. TiXmlText *PriceText = new TiXmlText( "22.5"); //创建XmlText
  24. Price->LinkEndChild(PriceText); //链接到Price下
  25. doc->SaveFile( "c:\\test.xml"); //保存到文件
  26. return 0;
  27. }


 


运行程序就可以在C盘根目录下找到那个命名为test.xml的XML文件了。使用记事本或者类似的文本工具就可以查看文件中的内容,如果写入成果文本的内容应该是和上面说给的一段XML内容一致了。



3、使用TinyXML读XML文件

有了上面写XML的经验,读XML文件相比更加的容易了。读XML文件相比写XML文件可能用的场合要更多一些。使用TinyXML读XML可以分为以下几个步骤:

1、创建一个TiXmlDocument文档对象;

2、加载XML文件;

3、获取文件根节点;

4、从根节点开始遍历读取。

直接使用一个比较复杂的XML文件来作为案例:


XML文件比较长不直接贴出,先从结构上来分析一下要读的这个XML文件。第一行是XML标识信息。然后上图中表红框的一对节点就是根节点了,读取的时候找到根节点,然后再去读取根节点下的子节点,依次进行下去就可以读取到我们想要的信息了。这里我想要的信息时存在于readingsession节点下的。

readingseassion节点下的内容前部分可以预览一下,文件太长不便于贴出。

  1. <readingSession>  
  2.     <annotationVersion>3.12</annotationVersion>  
  3.     <servicingRadiologistID>302474490</servicingRadiologistID>  
  4.     <unblindedReadNodule>  
  5.       <noduleID>Nodule 001</noduleID>  
  6.       <characteristics>  
  7.         <subtlety>5</subtlety>  
  8.         <internalStructure>1</internalStructure>  
  9.         <calcification>6</calcification>  
  10.         <sphericity>3</sphericity>  
  11.         <margin>3</margin>  
  12.         <lobulation>3</lobulation>  
  13.         <spiculation>5</spiculation>  
  14.         <texture>5</texture>  
  15.         <malignancy>5</malignancy>  
  16.       </characteristics>  
  17.       <roi>  
  18.         <imageZposition>-93.250000</imageZposition>  
  19.         <imageSOP_UID>1.3.6.1.4.1.14519.5.2.1.6279.6001.190268484503749714760575440541</imageSOP_UID>  
  20.         <inclusion>TRUE</inclusion>  
  21.         <edgeMap>  
  22.           <xCoord>311</xCoord>  
  23.           <yCoord>226</yCoord>  
  24.         </edgeMap>  
  25.         <edgeMap>  
  26.           <xCoord>310</xCoord>  
  27.           <yCoord>225</yCoord>  
  28.         </edgeMap>  
  29.         <edgeMap>  
  30.           <xCoord>309</xCoord>  
  31.           <yCoord>226</yCoord>  
  32.         </edgeMap>  

 
  1. <readingSession>
  2. <annotationVersion>3.12 </annotationVersion>
  3. <servicingRadiologistID>302474490 </servicingRadiologistID>
  4. <unblindedReadNodule>
  5. <noduleID>Nodule 001 </noduleID>
  6. <characteristics>
  7. <subtlety>5 </subtlety>
  8. <internalStructure>1 </internalStructure>
  9. <calcification>6 </calcification>
  10. <sphericity>3 </sphericity>
  11. <margin>3 </margin>
  12. <lobulation>3 </lobulation>
  13. <spiculation>5 </spiculation>
  14. <texture>5 </texture>
  15. <malignancy>5 </malignancy>
  16. </characteristics>
  17. <roi>
  18. <imageZposition>-93.250000 </imageZposition>
  19. <imageSOP_UID>1.3.6.1.4.1.14519.5.2.1.6279.6001.190268484503749714760575440541 </imageSOP_UID>
  20. <inclusion>TRUE </inclusion>
  21. <edgeMap>
  22. <xCoord>311 </xCoord>
  23. <yCoord>226 </yCoord>
  24. </edgeMap>
  25. <edgeMap>
  26. <xCoord>310 </xCoord>
  27. <yCoord>225 </yCoord>
  28. </edgeMap>
  29. <edgeMap>
  30. <xCoord>309 </xCoord>
  31. <yCoord>226 </yCoord>
  32. </edgeMap>


下面就可以写代码了,按照我们之前分析的读取顺序:

  1.          TiXmlDocument doc(pFile);  //pFile表示文件的路径                                      //创建读取XML临时对象  
  2. BOOL loadOK = doc.LoadFile();                                           //加载XML文件  
  3. if (!loadOK)                                                            //加载失败弹出提示并退出该函数  
  4. {  
  5.     MessageBox(NULL, "xml文件读取失败!""RBDcm提示您", MB_OK);  
  6.     return FALSE;  
  7. }  
  8.   
  9. TiXmlElement* root = doc.RootElement();                                 //XML的根节点  
  10. for (TiXmlNode* SpecialistItem = root->FirstChild("readingSession");    //对readingSession节点进行循环  
  11.     SpecialistItem; SpecialistItem = SpecialistItem->NextSibling("readingSession"))  
  12. {     
  13.     TiXmlNode* unblindedReadNodule = SpecialistItem->FirstChild("unblindedReadNodule");        
  14.     TiXmlNode* nonNodule = SpecialistItem->FirstChild("nonNodule");                            
  15.   
  16.     while (unblindedReadNodule)                             //节点unblindedReadNodule循环  
  17.     {  
  18.         TiXmlNode* roi = unblindedReadNodule->FirstChild("roi");  
  19.         while (roi)                                         //节点roi循环  
  20.         {  
  21.             SingleImgNodule single;    
  22.             TiXmlNode* imageZposition = roi->FirstChild("imageZposition");    //imageZposition信息  
  23.             const char* Zposition = imageZposition->ToElement()->GetText();    
  24.             single.ZPosition = CType::pChar2Double(Zposition);   
  25.             TiXmlNode* edgeMap = roi->FirstChild("edgeMap");   
  26.             while (edgeMap)                                                 //edgeMap节点循环  
  27.             {  
  28.                 TiXmlNode* xCoord = edgeMap->FirstChild("xCoord");  
  29.                 TiXmlNode* yCoord = edgeMap->FirstChild("yCoord");  
  30.                 const char* szX = xCoord->ToElement()->GetText();  
  31.                 const char* szY = yCoord->ToElement()->GetText();  
  32.                 NodulePoint pt;  
  33.                 pt.nt = ISNODULE;  
  34.                 pt.x = CType::pChar2int(szX);  
  35.                 pt.y = CType::pChar2int(szY);  
  36.                 single.vcNodulePoint.push_back(pt);  
  37.                 edgeMap = edgeMap->NextSibling("edgeMap");  
  38.             }  
  39.             m_vSingle.push_back(single);  
  40.             roi = roi->NextSibling("roi");  
  41.         }  
  42.         unblindedReadNodule = unblindedReadNodule->NextSibling("unblindedReadNodule");  
  43.     }  

 
  1. TiXmlDocument doc(pFile); //pFile表示文件的路径 //创建读取XML临时对象
  2. BOOL loadOK = doc.LoadFile(); //加载XML文件
  3. if (!loadOK) //加载失败弹出提示并退出该函数
  4. {
  5. MessageBox( NULL, "xml文件读取失败!", "RBDcm提示您", MB_OK);
  6. return FALSE;
  7. }
  8. TiXmlElement* root = doc.RootElement(); //XML的根节点
  9. for (TiXmlNode* SpecialistItem = root->FirstChild( "readingSession"); //对readingSession节点进行循环
  10. SpecialistItem; SpecialistItem = SpecialistItem->NextSibling( "readingSession"))
  11. {
  12. TiXmlNode* unblindedReadNodule = SpecialistItem->FirstChild( "unblindedReadNodule");
  13. TiXmlNode* nonNodule = SpecialistItem->FirstChild( "nonNodule");
  14. while (unblindedReadNodule) //节点unblindedReadNodule循环
  15. {
  16. TiXmlNode* roi = unblindedReadNodule->FirstChild( "roi");
  17. while (roi) //节点roi循环
  18. {
  19. SingleImgNodule single;
  20. TiXmlNode* imageZposition = roi->FirstChild( "imageZposition"); //imageZposition信息
  21. const char* Zposition = imageZposition->ToElement()->GetText();
  22. single.ZPosition = CType::pChar2Double(Zposition);
  23. TiXmlNode* edgeMap = roi->FirstChild( "edgeMap");
  24. while (edgeMap) //edgeMap节点循环
  25. {
  26. TiXmlNode* xCoord = edgeMap->FirstChild( "xCoord");
  27. TiXmlNode* yCoord = edgeMap->FirstChild( "yCoord");
  28. const char* szX = xCoord->ToElement()->GetText();
  29. const char* szY = yCoord->ToElement()->GetText();
  30. NodulePoint pt;
  31. pt.nt = ISNODULE;
  32. pt.x = CType::pChar2int(szX);
  33. pt.y = CType::pChar2int(szY);
  34. single.vcNodulePoint.push_back(pt);
  35. edgeMap = edgeMap->NextSibling( "edgeMap");
  36. }
  37. m_vSingle.push_back(single);
  38. roi = roi->NextSibling( "roi");
  39. }
  40. unblindedReadNodule = unblindedReadNodule->NextSibling( "unblindedReadNodule");
  41. }


上述代码来自于项目中的一小段源码,中间的有些量都是其它地方定义的,不必纠结于此,重要的是这个读取的流程。


转自:http://blog.youkuaiyun.com/robin__chou/article/details/501610

 

再见

 

 

 

评论 1
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值