C/C++编程:TinyXML学习

1059 篇文章 285 订阅

TinyXML是个解析库,主要由DOM模型类(TiXmlBase、TiXmlNode、TiXmlAttribute、TiXmlComment、TiXmlDeclaration、TiXmlElement、TiXmlText、TiXmlUnknown)和操作类(TiXmlHandler)构成。它由两个头文件(.h文件)和四个CPP文件(.cpp文件)构成,用的时候,只要将(tinyxml.h、tinystr.h、tinystr.cpp、tinyxml.cpp、tinyxmlerror.cpp、tinyxmlparser.cpp)导入工程就可以用它的东西了。如果需要,可以将它做成自己的DLL来调用。

例子

从文件中载入xml

#include <tinyxml.h>


void dump_to_stdout(const char* pFilename)
{
    TiXmlDocument doc(pFilename);
    bool loadOkay = doc.LoadFile();
    if (loadOkay)
    {
        printf("load file [ %s] ok\n", pFilename);
    }
    else
    {
        printf("Failed to load file \"%s\"\n", pFilename);
    }
}

int main()
{
    dump_to_stdout("xml/example1.xml");
    return 0;
}

在这里插入图片描述

以编程方式构建文档

文档一


#include <tinyxml.h>



void build_simple_doc( )
{
// Make xml: <?xml ..><Hello>World</Hello>
    TiXmlDocument doc;
    TiXmlDeclaration * decl = new TiXmlDeclaration( "1.0", "", "" );
    TiXmlElement * element = new TiXmlElement( "Hello" );
    TiXmlText * text = new TiXmlText( "World" );
    element->LinkEndChild( text );
    doc.LinkEndChild( decl );
    doc.LinkEndChild( element );
    doc.SaveFile( "madeByHand.xml" );
}

int main()
{
    build_simple_doc();
    return 0;
}


效果,生成一个文档,如下:

在这里插入图片描述
也可以这样写,效果和上面是一样的


#include <tinyxml.h>



void build_simple_doc( )
{
// Make xml: <?xml ..><Hello>World</Hello>
    TiXmlDocument doc;
    TiXmlDeclaration * decl = new TiXmlDeclaration( "1.0", "", "" );
    doc.LinkEndChild( decl );

    TiXmlElement * element = new TiXmlElement( "Hello" );
    doc.LinkEndChild( element );

    TiXmlText * text = new TiXmlText( "World" );
    element->LinkEndChild( text );

 
    doc.SaveFile( "madeByHand.xml" );
}

int main()
{
    build_simple_doc();
    return 0;
}



效果,生成一个文档,如下:

在这里插入图片描述

文档二


#include <tinyxml.h>



void write_app_settings_doc( ){
    TiXmlDocument doc;
    TiXmlElement *msg;
    TiXmlDeclaration* decl = new TiXmlDeclaration( "1.0", "", "" );
    doc.LinkEndChild(decl);

    TiXmlElement *root = new TiXmlElement("MyApp");
    doc.LinkEndChild(root);


    TiXmlComment * comment = new TiXmlComment();
    comment->SetValue(" Settings for MyApp " );
    root->LinkEndChild( comment );

    TiXmlElement * msgs = new TiXmlElement( "Messages" );
    root->LinkEndChild(msgs);

    msg = new TiXmlElement( "Welcome" );
    msg->LinkEndChild( new TiXmlText( "Welcome to MyApp" ));
    msgs->LinkEndChild( msg );

    msg = new TiXmlElement( "Farewell" );
    msg->LinkEndChild( new TiXmlText( "Thank you for using MyApp" ));
    msgs->LinkEndChild( msg );


    TiXmlElement * windows = new TiXmlElement( "Windows" );
    root->LinkEndChild( windows );

    TiXmlElement * window;
    window = new TiXmlElement( "Window" );
    windows->LinkEndChild( window );
    window->SetAttribute("name", "MainFrame");
    window->SetAttribute("x", 5);
    window->SetAttribute("y", 15);
    window->SetAttribute("w", 400);
    window->SetAttribute("h", 250);

    TiXmlElement * cxn = new TiXmlElement( "Connection" );
    root->LinkEndChild( cxn );
    cxn->SetAttribute("ip", "192.168.0.1");
    cxn->SetDoubleAttribute("timeout", 123.456); // floating point attrib


    doc.SaveFile( "appsettings.xml" );
}

int main()
{
    write_app_settings_doc();
    return 0;
}



在这里插入图片描述

属性

给定现有节点,设置属性很容易:

   auto window = new TiXmlElement( "Demo" );
    window->SetAttribute("name", "Circle");
    window->SetAttribute("x", 5);
    window->SetAttribute("y", 15);
    window->SetDoubleAttribute("radius", 3.14159);

测试一把:

#include <tinyxml.h>



void build_simple_doc( )
{

    TiXmlDocument doc;
    TiXmlDeclaration * decl = new TiXmlDeclaration( "1.0", "", "" );
    doc.LinkEndChild( decl );

    auto window = new TiXmlElement( "Demo" );
    doc.LinkEndChild( window );
    window->SetAttribute("name", "Circle");
    window->SetAttribute("x", 5);
    window->SetAttribute("y", 15);
    window->SetDoubleAttribute("radius", 3.14159);

    doc.SaveFile( "madeByHand.xml" );
}

int main()
{
    build_simple_doc();
    return 0;
}



在这里插入图片描述
遍历一个元素的所有属性:


#include <tinyxml.h>



int dump_attribs_to_stdout(TiXmlElement *pElement){
    if ( !pElement ) return 0;

    TiXmlAttribute* pAttrib=pElement->FirstAttribute();
    int i=0;
    int ival;
    double dval;


    while (pAttrib){
        printf( "Name=[%s]: value=[%s]", pAttrib->Name(), pAttrib->Value());
        if (pAttrib->QueryIntValue(&ival)==TIXML_SUCCESS)    printf( " int=%d", ival);
        if (pAttrib->QueryDoubleValue(&dval)==TIXML_SUCCESS) printf( " d=%1.1f", dval);
        printf( "\n" );
        i++;
        pAttrib=pAttrib->Next();
    }

    return i;
}

int main()
{
    auto window = new TiXmlElement( "Demo" );
    window->SetAttribute("name", "Circle");
    window->SetAttribute("x", 5);
    window->SetAttribute("y", 15);
    window->SetDoubleAttribute("radius", 3.14159);

    dump_attribs_to_stdout(window);
    return 0;
}

在这里插入图片描述

有很多方法可以做到这一点。具体参考:athttp://sourceforge.net/projects/tinybind

下面写一个最简单的

实例一


#include <tinyxml.h>

#include <string>
#include <map>
#include <list>

using namespace std;

typedef std::map<std::string, std::string> MessageMap;

class WindowSettings
{
public:
    int x,y,w,h;
    string name;

    WindowSettings()
            : x(0), y(0), w(100), h(100), name("Untitled")
    {
    }

    WindowSettings(int x, int y, int w, int h, const string& name)
    {
        this->x=x;
        this->y=y;
        this->w=w;
        this->h=h;
        this->name=name;
    }
};
class ConnectionSettings
{
public:
    string ip;
    double timeout;
};
class AppSettings
{
public:
    string m_name;
    MessageMap m_messages;
    std::list<WindowSettings> m_windows;
    ConnectionSettings m_connection;

    AppSettings() = default;

    void save(const char* pFilename);
    void load(const char* pFilename);

    // just to show how to do it
    void setDemoValues()
    {
        m_name="MyApp";
        m_messages.clear();
        m_messages["Welcome"]="Welcome to "+m_name;
        m_messages["Farewell"]="Thank you for using "+m_name;
        m_windows.clear();
        m_windows.emplace_back(15,15,400,250,"Main");
        m_connection.ip="Unknown";
        m_connection.timeout=123.456;
    }
};


void AppSettings::save(const char* pFilename)
{
    TiXmlDocument doc;
    TiXmlElement* msg;
    TiXmlComment * comment;
    string s;
    TiXmlDeclaration* decl = new TiXmlDeclaration( "1.0", "", "" );
    doc.LinkEndChild( decl );

    TiXmlElement * root = new TiXmlElement(m_name.c_str());
    doc.LinkEndChild( root );

    comment = new TiXmlComment();
    s=" Settings for "+m_name+" ";
    comment->SetValue(s.c_str());
    root->LinkEndChild( comment );

    // block: messages
    {
        MessageMap::iterator iter;

        TiXmlElement * msgs = new TiXmlElement( "Messages" );
        root->LinkEndChild( msgs );

        for (iter=m_messages.begin(); iter != m_messages.end(); iter++)
        {
            const string & key=(*iter).first;
            const string & value=(*iter).second;
            msg = new TiXmlElement(key.c_str());
            msg->LinkEndChild( new TiXmlText(value.c_str()));
            msgs->LinkEndChild( msg );
        }
    }

    // block: windows
    {
        TiXmlElement * windowsNode = new TiXmlElement( "Windows" );
        root->LinkEndChild( windowsNode );

        list<WindowSettings>::iterator iter;

        for (iter=m_windows.begin(); iter != m_windows.end(); iter++)
        {
            const WindowSettings& w=*iter;

            TiXmlElement * window;
            window = new TiXmlElement( "Window" );
            windowsNode->LinkEndChild( window );
            window->SetAttribute("name", w.name.c_str());
            window->SetAttribute("x", w.x);
            window->SetAttribute("y", w.y);
            window->SetAttribute("w", w.w);
            window->SetAttribute("h", w.h);
        }
    }

    // block: connection
    {
        TiXmlElement * cxn = new TiXmlElement( "Connection" );
        root->LinkEndChild( cxn );
        cxn->SetAttribute("ip", m_connection.ip.c_str());
        cxn->SetDoubleAttribute("timeout", m_connection.timeout);
    }

    doc.SaveFile(pFilename);
}

void AppSettings::load(const char* pFilename){
    TiXmlDocument doc(pFilename);
    if (!doc.LoadFile()) return;

    TiXmlHandle hDoc(&doc);
    TiXmlElement *pElem;
    TiXmlHandle hRoot(nullptr);

    // block: name
    {
        pElem = hDoc.FirstChildElement().Element();
        if (!pElem) return;
        m_name = pElem->Value();
        hRoot = TiXmlHandle(pElem);
    }

    // block: string table
    {
        m_messages.clear();

        pElem = hRoot.FirstChild("Message").FirstChild().Element();
        for( pElem; pElem; pElem=pElem->NextSiblingElement())
        {
            const char *pKey=pElem->Value();
            const char *pText=pElem->GetText();
            if (pKey && pText)
            {
                m_messages[pKey]=pText;
            }
        }
    }

    // block: windows
    {
        m_windows.clear(); // trash existing list

        TiXmlElement* pWindowNode=hRoot.FirstChild( "Windows" ).FirstChild().Element();
        for( pWindowNode; pWindowNode; pWindowNode=pWindowNode->NextSiblingElement())
        {
            WindowSettings w;
            const char *pName=pWindowNode->Attribute("name");
            if (pName) w.name=pName;

            pWindowNode->QueryIntAttribute("x", &w.x); // If this fails, original value is left as-is
            pWindowNode->QueryIntAttribute("y", &w.y);
            pWindowNode->QueryIntAttribute("w", &w.w);
            pWindowNode->QueryIntAttribute("hh", &w.h);

            m_windows.push_back(w);
        }
    }

    // block: connection
    {
        pElem=hRoot.FirstChild("Connection").Element();
        if (pElem)
        {
            m_connection.ip=pElem->Attribute("ip");
            pElem->QueryDoubleAttribute("timeout",&m_connection.timeout);
        }
    }
}
int main()
{
    AppSettings settings;
    settings.setDemoValues();
    settings.save("appsettings2.xml");
 //   settings.load("appsettings2.xml");
    return 0;
}



  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值