zoukankan      html  css  js  c++  java
  • tinyxml解析xml

    基于tinyxml做的简单的xml解析。

    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如下:

    <Response>
        <DeviceList Num="3">
            <Item>
                <DeviceID>44130000002000000002</DeviceID>
                <Name>测试平台</Name>
            </Item>
        </DeviceList>
    </Response>

    2.读取xml

    (1)从文件读取xml

    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)从字符串解析xml

    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的方式不同。

    从文件是:

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

    从字符串加载是:

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

    如字符串可以为:

    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反而会乱码,原因不明。

    // 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

  • 相关阅读:
    android —— textview解析html富文本
    android toolbar及可折叠标题栏
    dp——cf1327F
    cf1327D,E——组合数学
    技能表自查
    python 之禅 import this
    转--Python标准库之一句话概括
    python 爆破
    python -- 算法
    python 代码模板
  • 原文地址:https://www.cnblogs.com/betterwgo/p/7895891.html
Copyright © 2011-2022 走看看