TingXML学习记录之读写xml文档

TinyXML是一个开源的解析XML的解析库,能够用于C++,能够在Windows或Linux中编译。这个解析库的模型通过解析XML文件,然后在内存中生成DOM模型,从而让我们很方便的遍历这棵XML树。DOM模型即文档对象模型,是将整个文档分成多个元素(如书、章、节、段等),并利用树型结构表示这些元素之间的顺序关系以及嵌套包含关系。

在自己项目中使用TinyXML需要把六个cpp文件加入工程中,而且每个cpp文件需要包含stdafx.h头文件,否则报错,在文件中包含 tinyxml.h 头文件即可使用TinyXML,如下截图所示:



代码实现,例如我通过代码遍历下面的xml文件

<?xml version="1.0" encoding="UTF-8" standalone="yes" ?>
<Config>
  <Stock>
    <key stockScore="0" increaseProbability="0"/>
    <key stockScore="100000" increaseProbability="1.5"/>
    <key stockScore="300000" increaseProbability="2.0"/>
  </Stock>
  <pond>
    <money pondScore="0" increaseProbability="5"/>
    <money pondScore="100000" increaseProbability="2.5"/>
    <money pondScore="300000" increaseProbability="3.0"/>
  </pond>
</Config>

代码实现

TiXmlDocument mydoc;//xml文档对象
bool loadOk=mydoc.LoadFile("lkpy_config_33000306.xml",TIXML_ENCODING_UTF8);//根据UTF-8格式加载xml文档
if(!loadOk)
{
  exit(1);
}
TiXmlElement *RootElement=mydoc.RootElement();	//获取根节点Config
TiXmlElement *pEle=RootElement;
//遍历该节点
for(TiXmlElement *StuElement = pEle->FirstChildElement();//第一个子节点
    StuElement != NULL;
    StuElement = StuElement->NextSiblingElement())//下一个子节点
{
  if(0==strcmp(StuElement->Value(),"Stock"))//开始遍历名字为"Stock"的节点的子节点
  {
    for(TiXmlElement *stock = StuElement->FirstChildElement();stock != NULL;stock = stock->NextSiblingElement())
    {
      TiXmlAttribute *pAttr=stock->FirstAttribute();//得到节点的第一个属性
      while( NULL != pAttr) //输出所有属性
      {
        CString cs;
        cs.Format("lwlog::Name()=%s Value=%s",pAttr->Name(),pAttr->Value());
        OutputDebugString(cs);
        pAttr=pAttr->Next();
      }
    }
  }
  if(0==strcmp(StuElement->Value(),"pond"))
  {		
    for(TiXmlElement *pond = StuElement->FirstChildElement();pond != NULL;pond = pond->NextSiblingElement())
      {		
        TiXmlAttribute *pAttr=pond->FirstAttribute();
        while( NULL != pAttr) 
        {			
          CString cs;
          cs.Format("lwlog::Name()=%s Value=%s",pAttr->Name(),pAttr->Value());
          OutputDebugString(cs);
          pAttr=pAttr->Next();
        }
      }
  }			
}

打印结果


假如我有以下xml文档,我想读取节点key0,key1,key2属性stockScore的值到程序变量中,实现代码如下:

<?xml version="1.0" encoding="UTF-8" standalone="yes" ?>
<Config>
  <Stock>
    <key0 stockScore="0" increaseProbability="0"/>
    <key1 stockScore="100000" increaseProbability="1.5"/>
    <key2 stockScore="300000" increaseProbability="2.0"/>
    <key3>game</key3>
  </Stock>
  <pond>
    <money pondScore="0" increaseProbability="5"/>
    <money pondScore="100000" increaseProbability="2.5"/>
    <money pondScore="300000" increaseProbability="3.0"/>
  </pond>
</Config>
TiXmlDocument mydoc;//xml文档对象
bool loadOk=mydoc.LoadFile("lkpy_config_33000306.xml",TIXML_ENCODING_UTF8);//根据UTF-8格式加载xml文档
if(!loadOk)
{
  exit(1);
}
TiXmlElement *RootElement=mydoc.RootElement();	//获取根节点Config
TiXmlElement *pEle=RootElement;
int score[3]={0,0,0};
int index=0;
//遍历该节点
for(TiXmlElement *StuElement = pEle->FirstChildElement();//第一个子节点
    StuElement != NULL;
    StuElement = StuElement->NextSiblingElement())//下一个子节点
{
  if(0==strcmp(StuElement->Value(),"Stock"))//开始遍历名字为"Stock"的节点的子节点
  {
    for(TiXmlElement *stock = StuElement->FirstChildElement();stock != NULL;stock = stock->NextSiblingElement())
    {
      stock->Attribute("stockScore",&score[index++]);//存储属性值
    }
  }		
}

根据以上xml文档,我想读取节点key3的文本game,实现代码如下:

TiXmlDocument mydoc;//xml文档对象
bool loadOk=mydoc.LoadFile("lkpy_config_33000306.xml",TIXML_ENCODING_UTF8);//根据UTF-8格式加载xml文档
if(!loadOk)
{
  exit(1);
}
TiXmlElement *RootElement=mydoc.RootElement();	//获取根节点Config
TiXmlElement *pEle=RootElement;
//遍历该节点
for(TiXmlElement *StuElement = pEle->FirstChildElement();//第一个子节点
    StuElement != NULL;
    StuElement = StuElement->NextSiblingElement())//下一个子节点
{
  if(0==strcmp(StuElement->Value(),"Stock"))//开始遍历名字为"Stock"的节点的子节点
  {
    for(TiXmlElement *stock = StuElement->FirstChildElement();stock != NULL;stock = stock->NextSiblingElement())
    {
      if(0==strcmp(stock->Value(),"key3"))
        {
          const char *p=stock->GetText();//p指向字符串game
          CString cs;
          cs.Format("lwlog::p=%s",p);
          OutputDebugString(cs);
        }
    }
  }		
}

假如我想改写节点key2属性stockScore的值,实现代码如下:

TiXmlDocument mydoc;//xml文档对象
bool loadOk=mydoc.LoadFile("lkpy_config_33000306.xml",TIXML_ENCODING_UTF8);//根据UTF-8格式加载xml文档
if(!loadOk)
{
  exit(1);
}
TiXmlElement *RootElement=mydoc.RootElement();	//获取根节点Config
TiXmlElement *pEle=RootElement;
//遍历该节点
for(TiXmlElement *StuElement = pEle->FirstChildElement();//第一个子节点
    StuElement != NULL;
    StuElement = StuElement->NextSiblingElement())//下一个子节点
{
  if(0==strcmp(StuElement->Value(),"Stock"))//开始遍历名字为"Stock"的节点的子节点
  {
    for(TiXmlElement *stock = StuElement->FirstChildElement();stock != NULL;stock = stock->NextSiblingElement())
    {
      if(0==strcmp(stock->Value(),"key2"))
        {
          int n=123456;
          stock->SetAttribute("stockScore",n);//设置成我想要的值
        }
    }
  }		
}
mydoc.SaveFile();//记住一定要调用保存函数,否则修改无效

创建一个stu_info.xml文档

//创建xml文件
int writeXmlFile()
{
  TiXmlDocument *writeDoc = new TiXmlDocument; //xml文档指针
	
  //文档格式声明
  TiXmlDeclaration *decl = new TiXmlDeclaration("1.0", "UTF-8", "yes");
  writeDoc->LinkEndChild(decl); //写入文档

  int n = 3;	//父节点个数

  TiXmlElement *RootElement = new TiXmlElement("Info");//根元素
  RootElement->SetAttribute("num", n); //属性
  writeDoc->LinkEndChild(RootElement);
	
  for(int i=0; i<n; i++)//n个父节点
  {
    TiXmlElement *StuElement = new TiXmlElement("Stu");//Stu
    //设置属性
    StuElement->SetAttribute("class","A");
    if(2 == i)
    {
      StuElement->SetAttribute("class","B");
    }
		
    StuElement->SetAttribute("id",i+1);
    StuElement->SetAttribute("flag", (i+1)*10);
    RootElement->LinkEndChild(StuElement);//父节点写入文档
	
    //姓名
    TiXmlElement *nameElement = new TiXmlElement("name");
    StuElement->LinkEndChild(nameElement);

    TiXmlText *nameContent = new TiXmlText("mike");
    nameElement->LinkEndChild(nameContent);
		
    //分数
    TiXmlElement *scoreElement = new TiXmlElement("score");
    StuElement->LinkEndChild(scoreElement);

    TiXmlText *scoreContent = new TiXmlText("88");
    scoreElement->LinkEndChild(scoreContent);
		
    //城市
    TiXmlElement *cityElement = new TiXmlElement("city");
    StuElement->LinkEndChild(cityElement);

    TiXmlText *cityContent = new TiXmlText("Shenzhen");
    cityElement->LinkEndChild(cityContent);
		
  }
	
  writeDoc->SaveFile("stu_info.xml");
  delete writeDoc;
	
  return 1;
}

生成的xml文件内容如下:

<?xml version="1.0" encoding="UTF-8" standalone="yes" ?>
<Info num="3">
    <Stu class="A" id="1" flag="10">
        <name>mike</name>
        <score>88</score>
        <city>Shenzhen</city>
    </Stu>
    <Stu class="A" id="2" flag="20">
        <name>mike</name>
        <score>88</score>
        <city>Shenzhen</city>
    </Stu>
    <Stu class="B" id="3" flag="30">
        <name>mike</name>
        <score>88</score>
        <city>Shenzhen</city>
    </Stu>
</Info>
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值