天天看點

解析XML檔案 C++

最近突然想嘗試去解析XML檔案,網上查閱了一些資料,最後選用了TinyXML庫來解析,個人感覺還是很好用的,跟大家分享下一些心得和demo,希望能幫助到大家。

目錄

TinyXML 介紹

TinyXML 安裝和使用

TinyXML 主要類

XML讀寫demo

TinyXML 介紹

讀取和設定xml配置檔案是最常用的操作,TinyXML是一個開源的解析XML的C++解析庫,能夠在Windows或Linux中編譯。這個解析庫的模型通過解析XML檔案,然後在記憶體中生成DOM模型,進而讓我們很友善的周遊這棵XML樹。

Tinyxml的官方網址:http://www.grinninglizard.com

官方介紹文檔:http://www.grinninglizard.com/tinyxmldocs/tutorial0.html

TinyXML 安裝和使用

下載下傳TinyXML的網址:http://www.grinninglizard.com/tinyxml/

使用TinyXML隻需要将其中的6個檔案拷貝到項目中就可以直接使用了,這六個檔案是:tinyxml.h、tinystr.h、tinystr.cpp、tinyxml.cpp、tinyxmlerror.cpp、tinyxmlparser.cpp。

TinyXML 主要類

  • TiXmlBase:整個TinyXML模型的基類。
  • TiXmlAttribute:對應于XML中的元素的屬性。
  • TiXmlNode:對應于DOM結構中的節點。
  • TiXmlComment:對應于XML中的注釋
  • TiXmlDeclaration:對應于XML中的申明部分,即<?versiong="1.0" ?>。
  • TiXmlDocument:對應于XML的整個文檔。
  • TiXmlElement:對應于XML的元素。
  • TiXmlText:對應于XML的文字部分
  • TiXmlUnknown:對應于XML的未知部分。
  • TiXmlHandler:定義了針對XML的一些操作。

XML讀寫demo

#include "tinyxml.h"
#include <iostream>

struct CWindowSettings
{
    int x;
    int y;
    int w;
    int h;
    std::string name;
};

struct CConnection
{
    std::string ip;
    double timeout;
};

void WriteXML() 
{  
    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
    //dump_to_stdout( &doc );
    doc.SaveFile( "appsettings.xml" );  
}

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

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

    // block: name
    pElem = hDoc.FirstChildElement().Element();
    // should always have a valid root but handle gracefully if it does
    if (!pElem) 
        return;

    std::string name = pElem->Value();
    std::cout << name << std::endl;

    // save this for later
    hRoot=TiXmlHandle(pElem);

    // block: string table
    std::map<std::string, std::string> messages;
    pElem = hRoot.FirstChild( "Messages" ).FirstChild().Element();
    std::cout << std::endl;
    std::cout << "Messages" << std::endl;
    while (pElem)
    {
        std::string key = pElem->Value();
        std::string text = pElem->GetText();
        messages[key] = text;
        pElem = pElem->NextSiblingElement();

        std::cout << key << ": " << text << std::endl;
    }

    // block: windows
    std::vector<CWindowSettings> wondows;
    TiXmlElement* pWindowNode=hRoot.FirstChild( "Windows" ).FirstChild().Element();
    std::cout << std::endl;
    std::cout << "Windows" << std::endl;
    while (pWindowNode)
    {
        CWindowSettings w;
        w.name = pWindowNode->Attribute("name");
        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("h", &w.h);
        wondows.push_back(w);

        pWindowNode=pWindowNode->NextSiblingElement();
        std::cout << "Window" << ": " << "name=" << w.name << " "
                                      << "x=" << w.x << " "
                                      << "y=" << w.y << " "
                                      << "w=" << w.w << " "
                                      << "h=" << w.h << " "
                                      << std::endl;
    }

    // block: connection
    CConnection connection;
    pElem=hRoot.FirstChild("Connection").Element();
    std::cout << std::endl;
    std::cout << "Connection" << std::endl;
    if (pElem)
    {
        connection.ip = pElem->Attribute("ip");
        pElem->QueryDoubleAttribute("timeout",&connection.timeout);
        std::cout << "Connection: " << "ip=" << connection.ip << " " << "timeout=" << connection.timeout << std::endl;
    }
}

int _tmain(int argc, _TCHAR* argv[])
{
    WriteXML();
    LoadXML("appsettings.xml");
    return 0;
}
           

檔案:appsettings.xml

<?xml version="1.0" ?>
<MyApp>
    <!-- Settings for MyApp -->
    <Messages>
        <Welcome>Welcome to MyApp</Welcome>
        <Farewell>Thank you for using MyApp</Farewell>
    </Messages>
    <Windows>
        <Window name="MainFrame" x="5" y="15" w="400" h="250" />
    </Windows>
    <Connection ip="192.168.0.1" timeout="123.456" />
</MyApp>
           

輸出結果:

解析XML檔案 C++

參考:

https://www.cnblogs.com/hgwang/p/5833638.html

http://www.grinninglizard.com/tinyxmldocs/index.html

繼續閱讀