tinyxml解析xml

基於tinyxml作的簡單的xml解析。ios

1.建立xml

bool CreateXmlFile(string& szFileName)
{//建立xml文件,szFilePath爲文件保存的路徑,若建立成功返回true,不然false
    try
    {
        //建立一個XML的文檔對象。
        TiXmlDocument *myDocument = new TiXmlDocument();

        TiXmlElement *RootElement = new TiXmlElement("Response");
        myDocument->LinkEndChild(RootElement);

        TiXmlElement *DeviceListElement = new TiXmlElement("DeviceList");
        RootElement->LinkEndChild(DeviceListElement);

        DeviceListElement->SetAttribute("Num", "3");

        TiXmlElement *ItemElement = new TiXmlElement("Item");
        DeviceListElement->LinkEndChild(ItemElement);


        TiXmlElement *DeviceIDElement = new TiXmlElement("DeviceID");
        TiXmlElement *NameElement = new TiXmlElement("Name");
        ItemElement->LinkEndChild(DeviceIDElement);
        ItemElement->LinkEndChild(NameElement);

        TiXmlText *DeviceIDContent = new TiXmlText("44130000002000000002");
        TiXmlText *NameContent = new TiXmlText("測試平臺");
        DeviceIDElement->LinkEndChild(DeviceIDContent);
        NameElement->LinkEndChild(NameContent);

        myDocument->SaveFile(szFileName.c_str());//保存到文件
    }
    catch (string& e)
    {
        return false;
    }
    return true;
}

建立出來的xml以下:git

<Response>
    <DeviceList Num="3">
        <Item>
            <DeviceID>44130000002000000002</DeviceID>
            <Name>測試平臺</Name>
        </Item>
    </DeviceList>
</Response>

 

2.讀取xml

(1)從文件讀取xmlwindows

bool ReadXmlFile(string& szFileName)
{//讀取Xml文件,並遍歷
    try
    {
        //建立一個XML的文檔對象。
        TiXmlDocument *myDocument = new TiXmlDocument(szFileName.c_str());
        myDocument->LoadFile();
        //得到根元素,即Response。
        TiXmlElement *RootElement = myDocument->RootElement();
        //輸出根元素名稱,即輸出Response。
        cout << RootElement->Value() << endl;
        //得到第一個DeviceList節點。
        TiXmlElement *DeviceListElement = RootElement->FirstChildElement();
        TiXmlAttribute *NumAttribute = DeviceListElement->FirstAttribute();
        cout << NumAttribute->Value()<< endl;

        //得到第一個Person的name節點和age節點和ID屬性。
        TiXmlElement *ItemElement = DeviceListElement->FirstChildElement();
        for (int i = 0; i < 3; i++)
        {
            if (ItemElement)
            {
                TiXmlElement *DeviceIDElement = ItemElement->FirstChildElement();
                //這裏注意判斷是否存在,不然容易崩潰
                if (DeviceIDElement && DeviceIDElement->FirstChild())
                {
                    cout << DeviceIDElement->FirstChild()->Value() << endl;

                    TiXmlElement *NameElement = DeviceIDElement->NextSiblingElement();
                    if (NameElement && NameElement->FirstChild())
                    {
                        cout << NameElement->FirstChild()->Value() << endl;

                        TiXmlElement *ParentIDElement = NameElement->NextSiblingElement();
                        if (ParentIDElement && ParentIDElement->FirstChild())
                        {
                            cout << ParentIDElement->FirstChild()->Value() << endl;
                        }
                    }
                }

                ItemElement = ItemElement->NextSiblingElement();
            }
        }
    }
    catch (string& e)
    {
        return false;
    }
    return true;
}

(2)從字符串解析xmlide

bool ReadXmlString(string& xmlString, VEC_DEVICE& device_list)
{//讀取Xml文件,並遍歷
    try
    {
        //建立一個XML的文檔對象。
        TiXmlDocument *myDocument = new TiXmlDocument();
        myDocument->Parse(xmlString.c_str());
        //得到根元素,即Response。
        TiXmlElement *RootElement = myDocument->RootElement();
        //輸出根元素名稱,即輸出Response。
        cout << RootElement->Value() << endl;
        //得到第一個DeviceList節點。
        TiXmlElement *DeviceListElement = RootElement->FirstChildElement();
        TiXmlAttribute *NumAttribute = DeviceListElement->FirstAttribute();
        cout << NumAttribute->Value()<< endl;

        //得到第一個Person的name節點和age節點和ID屬性。
        TiXmlElement *ItemElement = DeviceListElement->FirstChildElement();
        ST_DEVICE_INFO device_info ;
        for (; ItemElement != NULL; ItemElement = ItemElement->NextSiblingElement())
        {
            if (ItemElement)
            {
                ST_DEVICE_INFO device_info;
                TiXmlElement *DeviceIDElement = ItemElement->FirstChildElement();
                if (DeviceIDElement && DeviceIDElement->FirstChild())
                {
                    string str = "";
                    str = DeviceIDElement->FirstChild()->Value();
                    //注意是否須要從utf-8轉爲GBK
                    device_info.m_strID = str.c_str();// UtfToGbk(str.c_str());
                    cout << "ID   "<<device_info.m_strID.c_str()<< endl;

                    TiXmlElement *NameElement = DeviceIDElement->NextSiblingElement();
                    if (NameElement && NameElement->FirstChild())
                    {
                        str = "";
                        str = NameElement->FirstChild()->Value();
                        device_info.m_strName = str.c_str();// UtfToGbk(str.c_str());
                        cout << "name  "<< device_info.m_strName << endl;

                        TiXmlElement *ParentIDElement = NameElement->NextSiblingElement();
                        if (ParentIDElement && ParentIDElement->FirstChild())
                        {
                            str = "";
                            str = ParentIDElement->FirstChild()->Value();
                            device_info.m_strParentID = str.c_str();// UtfToGbk(str.c_str());
                            cout << "m_strParentID  "<<device_info.m_strParentID.c_str()<< endl;
                        }

                        device_info.m_nStatus = 1;

                        device_list.push_back(device_info);
                    }
                }
                else
                {
                    continue;
                }
            }
        }
    }
    catch (string& e)
    {
        return false;
    }
    return true;
}

 

從文件解析xml與從字符串解析xml的不一樣僅僅在加載xml的方式不一樣。測試

從文件是:spa

TiXmlDocument *myDocument = new TiXmlDocument(szFileName.c_str()); //szFileName爲文件路徑名
myDocument->LoadFile();

從字符串加載是:code

TiXmlDocument *myDocument = new TiXmlDocument();
myDocument->Parse(xmlString.c_str());    //xmlString是字符串

如字符串能夠爲:xml

string xmlStr = "\
                <?xml version=\"1.0\" encoding=\"utf - 8\" standalone=\"no\" ?> \
                <Response>\
                    <DeviceList Num=\"3\">\
                        <Item>\
                            <DeviceID>44130000002000000002</DeviceID>\
                            <Name>測試平臺</Name>\
                        </Item>\
                        <Item>\
                            <DeviceID>441301</DeviceID>\
                            <Name>惠州市</Name>\
                            <ParentID>44130000002000000002</ParentID>\
                        </Item>\
                        <Item>\
                            <DeviceID>44130000002000000068</DeviceID>\
                            <Name>郵政儲蓄門口</Name>\
                            <ParentID>441301</ParentID>\
                        </Item>\
                        <Item>\
                            <DeviceID>44130000002000000068</DeviceID>\
                            <Name>郵政儲蓄門口</Name>\
                            <ParentID>441301</ParentID>\
                        </Item>\
                        <Item>\
                            <DeviceID>44130000002000000068</DeviceID>\
                            <Name>郵政儲蓄門口</Name>\
                            <ParentID>441301</ParentID>\
                        </Item>\
                        <Item>\
                            <DeviceID>44130000002000000068</DeviceID>\
                            <Name>郵政儲蓄門口</Name>\
                            <ParentID>441301</ParentID>\
                        </Item>\
                        <Item>\
                            <DeviceID>44130000002000000068</DeviceID>\
                            <Name>郵政儲蓄門口</Name>\
                            <ParentID>441301</ParentID>\
                        </Item>\
                        <Item>\
                            <DeviceID>44130000002000000068</DeviceID>\
                            <Name>郵政儲蓄門口</Name>\
                            <ParentID>441301</ParentID>\
                        </Item>\
                    </DeviceList>\
                </Response>" ;

有的時候須要從UTF-8轉GBK,不然會亂碼:對象

std::string UtfToGbk(const char* utf8)
{
    int len = MultiByteToWideChar(CP_UTF8, 0, utf8, -1, NULL, 0);
    wchar_t* wstr = new wchar_t[len + 1];
    memset(wstr, 0, len + 1);
    MultiByteToWideChar(CP_UTF8, 0, utf8, -1, wstr, len);
    len = WideCharToMultiByte(CP_ACP, 0, wstr, -1, NULL, 0, NULL, NULL);
    char* str = new char[len + 1];
    memset(str, 0, len + 1);
    WideCharToMultiByte(CP_ACP, 0, wstr, -1, str, len, NULL, NULL);
    if (wstr) delete[] wstr;
    return str;
}

 

3.完整的demo

如下是VS2013上的一個例子,搞怪的是utf-8轉成GBK也不會亂碼,轉成GBK反而會亂碼,緣由不明。blog

// xmlTest.cpp : 定義控制檯應用程序的入口點。
//

#include "stdafx.h"

#include <iostream>
#include <string>
#include <windows.h>
#include <atlstr.h>
#include <vector>

#define TIXML_USE_STL
#include "tinyxml.h"
#include "tinystr.h"

#pragma comment(lib,"tinyxmlSTL.lib")

using namespace std;

struct ST_DEVICE_INFO
{
    string m_strID;                 //設備ID
    string m_strParentID;           //父ID
    string m_strName;               //設備名

    int m_nType;                    //類型
    int m_nStatus;                  //狀態

    float m_fLongitude;             //經度
    float m_fLatitude;              //緯度

    ST_DEVICE_INFO()
    {
        m_strID.clear();
        m_strParentID.clear();
        m_strName.clear();

        m_nType = 0;
        m_nStatus = 0;

        m_fLongitude = 0;
        m_fLatitude = 0;
    }
};
typedef vector<ST_DEVICE_INFO> VEC_DEVICE;

std::string UtfToGbk(const char* utf8)
{
    int len = MultiByteToWideChar(CP_UTF8, 0, utf8, -1, NULL, 0);
    wchar_t* wstr = new wchar_t[len + 1];
    memset(wstr, 0, len + 1);
    MultiByteToWideChar(CP_UTF8, 0, utf8, -1, wstr, len);
    len = WideCharToMultiByte(CP_ACP, 0, wstr, -1, NULL, 0, NULL, NULL);
    char* str = new char[len + 1];
    memset(str, 0, len + 1);
    WideCharToMultiByte(CP_ACP, 0, wstr, -1, str, len, NULL, NULL);
    if (wstr) delete[] wstr;
    return str;
}

bool CreateXmlFile(string& szFileName)
{//建立xml文件,szFilePath爲文件保存的路徑,若建立成功返回true,不然false
    try
    {
        //建立一個XML的文檔對象。
        TiXmlDocument *myDocument = new TiXmlDocument();

        TiXmlElement *RootElement = new TiXmlElement("Response");
        myDocument->LinkEndChild(RootElement);

        TiXmlElement *DeviceListElement = new TiXmlElement("DeviceList");
        RootElement->LinkEndChild(DeviceListElement);

        DeviceListElement->SetAttribute("Num", "3");

        TiXmlElement *ItemElement = new TiXmlElement("Item");
        DeviceListElement->LinkEndChild(ItemElement);


        TiXmlElement *DeviceIDElement = new TiXmlElement("DeviceID");
        TiXmlElement *NameElement = new TiXmlElement("Name");
        ItemElement->LinkEndChild(DeviceIDElement);
        ItemElement->LinkEndChild(NameElement);

        TiXmlText *DeviceIDContent = new TiXmlText("44130000002000000002");
        TiXmlText *NameContent = new TiXmlText("測試平臺");
        DeviceIDElement->LinkEndChild(DeviceIDContent);
        NameElement->LinkEndChild(NameContent);

        myDocument->SaveFile(szFileName.c_str());//保存到文件
    }
    catch (string& e)
    {
        return false;
    }
    return true;
}

bool ReadXmlFile(string& szFileName)
{//讀取Xml文件,並遍歷
    try
    {
        //建立一個XML的文檔對象。
        TiXmlDocument *myDocument = new TiXmlDocument(szFileName.c_str());
        myDocument->LoadFile();
        //得到根元素,即Response。
        TiXmlElement *RootElement = myDocument->RootElement();
        //輸出根元素名稱,即輸出Response。
        cout << RootElement->Value() << endl;
        //得到第一個DeviceList節點。
        TiXmlElement *DeviceListElement = RootElement->FirstChildElement();
        TiXmlAttribute *NumAttribute = DeviceListElement->FirstAttribute();
        cout << NumAttribute->Value()<< endl;

        //得到第一個Person的name節點和age節點和ID屬性。
        TiXmlElement *ItemElement = DeviceListElement->FirstChildElement();
        for (int i = 0; i < 3; i++)
        {
            if (ItemElement)
            {
                TiXmlElement *DeviceIDElement = ItemElement->FirstChildElement();
                //這裏注意判斷是否存在,不然容易崩潰
                if (DeviceIDElement && DeviceIDElement->FirstChild())
                {
                    cout << DeviceIDElement->FirstChild()->Value() << endl;

                    TiXmlElement *NameElement = DeviceIDElement->NextSiblingElement();
                    if (NameElement && NameElement->FirstChild())
                    {
                        cout << NameElement->FirstChild()->Value() << endl;

                        TiXmlElement *ParentIDElement = NameElement->NextSiblingElement();
                        if (ParentIDElement && ParentIDElement->FirstChild())
                        {
                            cout << ParentIDElement->FirstChild()->Value() << endl;
                        }
                    }
                }

                ItemElement = ItemElement->NextSiblingElement();
            }
        }
    }
    catch (string& e)
    {
        return false;
    }
    return true;
}

bool ReadXmlString(string& xmlString, VEC_DEVICE& device_list)
{//讀取Xml文件,並遍歷
    try
    {
        //建立一個XML的文檔對象。
        TiXmlDocument *myDocument = new TiXmlDocument();
        myDocument->Parse(xmlString.c_str());
        //得到根元素,即Response。
        TiXmlElement *RootElement = myDocument->RootElement();
        //輸出根元素名稱,即輸出Response。
        cout << RootElement->Value() << endl;
        //得到第一個DeviceList節點。
        TiXmlElement *DeviceListElement = RootElement->FirstChildElement();
        TiXmlAttribute *NumAttribute = DeviceListElement->FirstAttribute();
        cout << NumAttribute->Value()<< endl;

        //得到第一個Person的name節點和age節點和ID屬性。
        TiXmlElement *ItemElement = DeviceListElement->FirstChildElement();
        ST_DEVICE_INFO device_info ;
        for (; ItemElement != NULL; ItemElement = ItemElement->NextSiblingElement())
        {
            if (ItemElement)
            {
                ST_DEVICE_INFO device_info;
                TiXmlElement *DeviceIDElement = ItemElement->FirstChildElement();
                if (DeviceIDElement && DeviceIDElement->FirstChild())
                {
                    string str = "";
                    str = DeviceIDElement->FirstChild()->Value();
                    //注意是否須要從utf-8轉爲GBK
                    device_info.m_strID = str.c_str();// UtfToGbk(str.c_str());
                    cout << "ID   "<<device_info.m_strID.c_str()<< endl;

                    TiXmlElement *NameElement = DeviceIDElement->NextSiblingElement();
                    if (NameElement && NameElement->FirstChild())
                    {
                        str = "";
                        str = NameElement->FirstChild()->Value();
                        device_info.m_strName = str.c_str();// UtfToGbk(str.c_str());
                        cout << "name  "<< device_info.m_strName << endl;

                        TiXmlElement *ParentIDElement = NameElement->NextSiblingElement();
                        if (ParentIDElement && ParentIDElement->FirstChild())
                        {
                            str = "";
                            str = ParentIDElement->FirstChild()->Value();
                            device_info.m_strParentID = str.c_str();// UtfToGbk(str.c_str());
                            cout << "m_strParentID  "<<device_info.m_strParentID.c_str()<< endl;
                        }

                        device_info.m_nStatus = 1;

                        device_list.push_back(device_info);
                    }
                }
                else
                {
                    continue;
                }
            }
        }
    }
    catch (string& e)
    {
        return false;
    }
    return true;
}

int _tmain(int argc, _TCHAR* argv[])
{
    string fileName = "test.xml";
    CreateXmlFile(fileName);

    cout << "xml文件解析:" << endl;
    ReadXmlFile(fileName);

    cout << endl;
    cout << "字符串解析:" << endl;

    string xmlStr = "\
                <?xml version=\"1.0\" encoding=\"utf - 8\" standalone=\"no\" ?> \
                <Response>\
                    <DeviceList Num=\"3\">\
                        <Item>\
                            <DeviceID>44130000002000000002</DeviceID>\
                            <Name>測試平臺</Name>\
                        </Item>\
                        <Item>\
                            <DeviceID>441301</DeviceID>\
                            <Name>惠州市</Name>\
                            <ParentID>44130000002000000002</ParentID>\
                        </Item>\
                        <Item>\
                            <DeviceID>44130000002000000068</DeviceID>\
                            <Name>郵政儲蓄門口</Name>\
                            <ParentID>441301</ParentID>\
                        </Item>\
                        <Item>\
                            <DeviceID>44130000002000000068</DeviceID>\
                            <Name>郵政儲蓄門口</Name>\
                            <ParentID>441301</ParentID>\
                        </Item>\
                        <Item>\
                            <DeviceID>44130000002000000068</DeviceID>\
                            <Name>郵政儲蓄門口</Name>\
                            <ParentID>441301</ParentID>\
                        </Item>\
                        <Item>\
                            <DeviceID>44130000002000000068</DeviceID>\
                            <Name>郵政儲蓄門口</Name>\
                            <ParentID>441301</ParentID>\
                        </Item>\
                        <Item>\
                            <DeviceID>44130000002000000068</DeviceID>\
                            <Name>郵政儲蓄門口</Name>\
                            <ParentID>441301</ParentID>\
                        </Item>\
                        <Item>\
                            <DeviceID>44130000002000000068</DeviceID>\
                            <Name>郵政儲蓄門口</Name>\
                            <ParentID>441301</ParentID>\
                        </Item>\
                    </DeviceList>\
                </Response>" ;

    VEC_DEVICE device_list ;
    device_list.clear() ;
    ReadXmlString(xmlStr, device_list) ;
    cout << endl;

    for (int i = 0; i < device_list.size(); i++)
    {
        cout<< "設備ID:" <<device_list[i].m_strID<<"  設備名稱:"<<device_list[i].m_strName<<"   父ID: "<<device_list[i].m_strParentID<<endl ;
    }

    system("pause");

    return 0;
}

運行結果:

image

 

完整工程地址:https://gitee.com/betterwgo/timyxml

相關文章
相關標籤/搜索