TinyXml的基本用法

        有人说xml格式文件(简称xml)就是一个小型的数据库,对数据库的任何操作可以在xml格式上完成后,笔者对数据库以及xml的使用还没有达到这种地步,所以也就没有权利评价这句话,但是从这句话我们可以知道xml的重要性。一般的xml用作保存一些配置信息,或者是类的序列化,配置文件使用的比较多。既然使用了xml,那就需要寻找一种解析xml的利器。现提供的解析xml的利器非常的多,比如有通用的DOM(DOM 是用与平台和语言无关的方式表示 XML 文档的官方 W3C 标准,摘自:http://hi.baidu.com/dvvjktshrwdosve/item/13d9c0cab21a1e3398b498f4)、xmlparser、tinyXMl(C++实现开源)等,DOM解析工具功能强大,但是结构复杂,对于解析配置文件这样的小型的xml文件时杀鸡用牛刀。由于使用的次数和深度有限,本文就分享tinyxml的基本用法。

    (一) tinyxml是开源的解析xml库,在遵循开源协议下可以查看和修改源代码,其基本的结构如下

           1)TiXmlVisitor:是解析xml重要的访问器,负责遍历所有的xml节点,用户一般不会使用;

           2)TiXmlBase:是所有的tinyXml中的类的父类,除了可以建立文档,还有输出文档的结构等接口;

           3)TiXmlNode:是除了属性类之外的所有的xml文档结构模型的父类,是一个比较实用的类,提供了对其父子兄弟节点的指针以及操作;

           4)TiXmlAttribute:xml节点的属性类,其直接继承自TiXmlBase类,提供了对节点属性的操作;

           5)TiXmlAttributeSet:管理一系列的属性类;

           6)TiXmlElement:这是一个容器类,它包具有值,节点的名称,也可以包含其他的element、text、等,可以讲node转化为element方便用户操作;

           7)TiXmlComment:xml的命令类,提供了对xml整体的操作

           8)TiXmlText:是节点的值类,提供了对节点的值的操作

           9)TiXmlDeclaration:xml的头描述信息的类,主要控制版本、编码等

           10)TiXmlUnknown:解析工具无法识别的类,主要是不规范的节点

           11)TiXmlDocument:是建立xml的核心类,是xml最顶层的节点类,包含其他多有的xml节点

           12)TiXmlHandle:是提供的tinyXml中的工具,其不适宜tinyXml的结构,主要是包裹一个节点的指针,并进行空检查

           13)TiXmlPrinter:是一些打印操作的类,一般不是很常用

   (二)tiny操作下面的xml(下面的这段xml格式出处忘记了,在此对原作者表示道歉),主要从建立、读取、修改三个方面简述

     例子xml:

     <?xml version="1.0" encoding="UTF-8" standalone="yes" ?>
     <ZXML>
      <ZAPP>
         <VBS_RUNTIME_PARAMS>
               <BROADCAST_VERSION info="版本">8</BROADCAST_VERSION>
               <Broadcast>
                    <FileCount info="资源文件个数">69</FileCount>
                    <SOURCE_1>
                        <ID info="图片编号">1</ID>
                        <Version info="图片版本">1</Version>
                        <Path info="图片路径">/mnt/share/1.bmp</Path>
                        <FileMode info="文件处理模式">0</FileMode>
                    </SOURCE_1>
                </Broadcast>
         </VBS_RUNTIME_PARAMS>
    </ZAPP>
    </ZXML>

    1)建立xml

    //建立xml的top节点,并设置名称为Test_2.xml

    TiXmlDocument* document = new TiXmlDocument("Test_2.xml");
    if(!document)
    {
        return;
    }

    //建立描述节点,设置了版本和字符编码,并添加到top节点
    TiXmlDeclaration* declaration = new TiXmlDeclaration("1.1.0", "UTF-8", "");
    if(!declaration)
    {
        return;
    }
    document->LinkEndChild(declaration);

    //建立第二级节点,并添加到top节点
    TiXmlNode* nodeZXML = new TiXmlElement("ZXML");
    document->LinkEndChild(nodeZXML);

    //建立第二级节点,添加到第一节点下
    TiXmlNode* nodeZAPP= new TiXmlElement("ZAPP");
    nodeZXML->LinkEndChild(nodeZAPP);

    TiXmlNode* nodeVBS_RUNTIME_PARAMS = new TiXmlElement("VBS_RUNTIME_PARAMS");
    nodeZAPP->LinkEndChild(nodeVBS_RUNTIME_PARAMS);

    TiXmlNode* nodeBROADCAST_VERSION = new TiXmlElement("BROADCAST_VERSION");
    nodeVBS_RUNTIME_PARAMS->LinkEndChild(nodeBROADCAST_VERSION);

   //设置节点的值,并添加到节点上
    TiXmlText* textBROADCAST_VERSION = new TiXmlText("8");
    nodeBROADCAST_VERSION->LinkEndChild(textBROADCAST_VERSION);

    nodeBROADCAST_VERSION->ToElement()->SetAttribute("info", "版本");

    TiXmlElement* nodeBroadcast = new TiXmlElement("Broadcast");
    nodeBROADCAST_VERSION->LinkEndChild(nodeBroadcast);

    //设置节点的属性值
    TiXmlElement* nodeFileCount = new TiXmlElement("FileCount");
    TiXmlText* countText = new TiXmlText("69");
    nodeFileCount->LinkEndChild(countText);
    nodeFileCount->SetAttribute("info", "资源文件个数");
    nodeBroadcast->LinkEndChild(nodeFileCount);

    TiXmlElement* nodeSOURCE_1 = new TiXmlElement("SOURCE_1");
    nodeBroadcast->LinkEndChild(nodeSOURCE_1);

    TiXmlElement* nodeID_1 = new TiXmlElement("ID");
    TiXmlText* textIDInfo_1 = new TiXmlText("1");
    nodeID_1->LinkEndChild(textIDInfo_1);
    nodeID_1->SetAttribute("info", "图片编号");
    nodeSOURCE_1->LinkEndChild(nodeID_1);

    TiXmlElement* nodeVersion_1 = new TiXmlElement("Version");
    TiXmlText* textVersionInfo_1 = new TiXmlText("1");
    nodeVersion_1->LinkEndChild(textVersionInfo_1);
    nodeVersion_1->SetAttribute("info", "图片版本");
    nodeSOURCE_1->LinkEndChild(nodeVersion_1);

    TiXmlElement* nodePath_1 = new TiXmlElement("Path");
    TiXmlText* textPathInfo = new TiXmlText("1");
    nodePath_1->LinkEndChild(textPathInfo);
    nodePath_1->SetAttribute("info", "图片路径");
    nodeSOURCE_1->LinkEndChild(nodePath_1);


    TiXmlElement* nodeFileMode_1 = new TiXmlElement("FileMode");
    TiXmlText* textFileModeInfo = new TiXmlText("0");
    nodeFileMode_1->LinkEndChild(textFileModeInfo);
    nodeFileMode_1->SetAttribute("info", "文件处理模式");
    nodeSOURCE_1->LinkEndChild(nodeFileMode_1);

    //保存文档
    bool returnValue = document->SaveFile();

    2)读取xml

   //通过指定的路径,建立读取的文档

   TiXmlDocument doc;
    if(!doc.LoadFile("test_2.xml"))
    {
        return;
    }

    //使用handle来遍历节点
    TiXmlHandle* root = new TiXmlHandle(&doc);
    if(!root)
    {
        return;
    }

    //获得指定的节点,并转化成TiXmlElement的类型,方便处理
    TiXmlElement* element = root->FirstChild("ZXML").FirstChild("ZAPP").FirstChild("VBS_RUNTIME_PARAMS").FirstChild("BROADCAST_VERSION").ToElement();

    if(!element)
    {
        return;
    }
    const char* val = NULL;
    val = element->GetText();

    if(val)
    {
        //版本号
        std::string version = val;
    }


    val = element->Attribute("info");

    if(val)
    {
        //版本属性
        std::string info = val;

    }

    
    element = element->FirstChildElement("Broadcast")->FirstChildElement("FileCount");

    if(!element)
    {
        return;
    }

    val = element->GetText();
    if(val)
    {
        std::string count = val;
    }

    val = element->Attribute("info");
    if(val)
    {
        std::string infoCount = val;
    }

    element = element->NextSiblingElement("SOURCE_1");

    if(!element)
    {
        return;
    }

    element = element->FirstChildElement("ID");
    if(!element)
    {
        return;
    }

    val = element->GetText();
    if(val)
    {
        std::string IDText = val;
    }

    val = element->Attribute("info");
    if(val)
    {
        std::string IDinfo = val;
    }

    element = element->NextSiblingElement();
    if(!element)
    {
        return;
    }

   //获得节点的值
    val = element->GetText();
    if(val)
    {
        std::string verText = val;
    }

   //获得节点的属性
    val = element->Attribute("info");
    if(val)
    {
        std::string verInfo = val;
    }

    //下一个兄弟节点
    element = element->NextSiblingElement();
    if(!element)
    {
        return;
    }

    val = element->GetText();
    if(val)
    {
        std::string pathText = val;
    }

    val = element->Attribute("info");
    if(val)
    {
        std::string pathInfo = val;
    }

    element = element->NextSiblingElement();
    if(!element)
    {
        return;
    }

    val = element->GetText();
    if(val)
    {
        std::string nodeText = val;
    }

    val = element->Attribute("info");
    if(val)
    {
        std::string nodeInfo = val;
    }

    element = element->Parent()->ToElement();
    if(!element)
    {
        return;
    }

    element = element->NextSiblingElement();
    if(!element)
    {
        return;
    }

    element = element->FirstChildElement("Path");
    if(!element)
    {
        return;
    }

    val = element->GetText();
    if(val)
    {
        std::string pathInfo = val;
    }

    3)修改xml文档

  TiXmlDocument doc("test_2.xml");
    if(!doc.LoadFile())
    {
        return;
    }

    TiXmlHandle* handle = new TiXmlHandle(&doc);
    if(!handle)
    {
        return;
    }
    /**增加节点的代码
    TiXmlElement* element = handle->FirstChildElement().FirstChildElement("ZAPP").ToElement();
    if(!element)
    {
        return;
    }

   //在element节点之前和之后插入一个节点
    TiXmlElement* addNode_1 = new TiXmlElement("AddNode_1");
    if(!addNode_1)
    {
        return;
    }
    //element->Parent()->InsertAfterChild(element, *addNode_1);
    element->Parent()->InsertBeforeChild(element, *addNode_1);

    TiXmlElement* addNode_2 = new TiXmlElement("AddNode_2");
    if(!addNode_2)
    {
        return;
    }

   //增加节点的值
    TiXmlText* text = new TiXmlText("test_text");
    addNode_2->LinkEndChild(text);
    element->InsertEndChild(*addNode_2);

    ***/

    //重新设置属性,如果没有添加属性,有修改属性
    TiXmlElement* element = handle->FirstChild("ZXML").FirstChild("ZAPP").FirstChild("VBS_RUNTIME_PARAMS").FirstChild("BROADCAST_VERSION").ToElement();
    if(!element)
    {
        return;
    }

    element->SetAttribute("info", "版本新");
    //element->FirstChild()->setT

   //保存修改
    doc.SaveFile("test_4.xml");


   (三)注意事项

     一般读取xml,大多数人喜欢使用std::tring接受解析的值,但是假如节点不存在返回的是char* 的NULL值,这样直接的传给string就会导致崩溃,一般先以char*接受然后验证是否为空。

tinyXml的简单介绍就完成了,不足和错误之处,希望大家能够指出并交流,本人非常感谢!


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值