zoukankan      html  css  js  c++  java
  • 类xml数据格式解析

    需要解析一种类xml的数据文件,数据格式1如下:

    <head> //文件头
        <type>xtype</type>
        <condition>
            key1=value1
            key2=value2
        </condition>
        <mea>
            key3=value3
            key4=value4
        </mea>
        <xxxx>//多个
         ...
         </xxx>
    </head>
    <data> //数据域,多个
    phi rcs ang
    1    2    3
    2    3    4
    </data>
    <data>
    phi rcs ang
    3    4    5
    4    5    6
    </data>
    数据格式2:
    #xtype
    //comment
    [condition]
        项1=值1
        项2=值2
    [/condition]
    [mea]
        key3=value3
        key4=value4
    [/mea]
    [data]
    phi rcs ang
    1    1    1
    2    2    2
    [/data]
    [data]
    phi rcs ang
    3    1    1
    4    2    2
    [/data]

    该数据格式类似xml,我们需要解析的是head中的所有标签,及标签中的键值对(key=value),并将data域中的数据保存成浮点型数组。

    采用类似xml的解析方式,递归进行解析

     具体代码如下:

    #ifndef MYPARSEGJBDATA_H_20170114
    #define MYPARSEGJBDATA_H_20170114
    
    #include <string>
    #include <map>
    #include <vector>
    #include <iostream>
    #include <fstream>
    #include <sstream>
    using namespace std;
    
    /*file format1:
    <head>
        <type>xtype</type>
        <conditon>
            key1=value1
            key2=value2
        </condition>
        <mea>
            key3=value3
            key4=value4
        </mea>
    </head>
    <data>
    phi rcs ang
    1    1    1
    2    2    2
    </data>
    */
    
    typedef struct stMyDataLabel{
        string Label;//标签名称
        vector<string> Content;//对于<lable>content</label>的形式,纯字符串,非键值对
        vector<float>  Values;//对应数据域,一维数组表示二维数组;数组的列数为Contens'size
        map<string,string> KeyVal;//<label>内的键值对
        vector<stMyDataLabel> SubItems;//子节点列表
    
        stMyDataLabel(){
            Label = "";
            Content.clear();
            Values.clear();
            KeyVal.clear();
            SubItems.clear();
        }
        void Clear(){//递归清空内存
            for (vector<stMyDataLabel>::iterator itr = SubItems.begin();itr!=SubItems.end();itr++)
            {
                itr->Clear();
            }
            Content.clear();
            Values.clear();
            KeyVal.clear();
            SubItems.clear();
        }
    
        friend ostream& operator <<(ostream& myout,stMyDataLabel& m_Data){//输出流
            myout<<m_Data.Label<<endl;
            for (vector<string>::iterator sitr = m_Data.Content.begin(); sitr != m_Data.Content.end(); sitr++)
            {
                myout<<"	"<<*sitr<<"	";
            }
            myout<<endl;
            for (auto mitr = m_Data.KeyVal.begin(); mitr != m_Data.KeyVal.end(); mitr++)
            {
                myout<<"	"<<mitr->first<<" = "<<mitr->second<<"	";
            }
            myout<<endl;
    
            int dsize = m_Data.Content.size();
            int curdidx = 0;
            for(vector<float>::iterator fitr = m_Data.Values.begin(); fitr != m_Data.Values.end(); fitr++){
                myout<<"	"<<*fitr<<"	";
                curdidx++;
                if(curdidx >= dsize){
                    cout<<endl;
                    curdidx=0;
                }
            }
            myout<<endl;
            for (vector<stMyDataLabel>::iterator itr = m_Data.SubItems.begin();itr != m_Data.SubItems.end(); itr++)
            {
                myout<<*itr<<endl;
            }
            return myout;
        }
    }stMyDataLabel;
    
    class MyDataParse{//数据类型1的解析类
    public:
        vector<stMyDataLabel> m_Data;
        stMyDataLabel m_Header;
        char m_StartLabel;
        char m_EndLabel;
    public:
        MyDataParse(){
            m_StartLabel = '<';
            m_EndLabel = '>';
        }
        void Init(){
            m_Header.Clear();
            for (vector<stMyDataLabel>::iterator itr = m_Data.begin();itr!=m_Data.end();itr++)
            {
                itr->Clear();
            }
        }
    
        void Print(ostream& myout){
            myout<<m_Header<<endl;
            for (vector<stMyDataLabel>::iterator ditr = m_Data.begin();ditr!=m_Data.end();ditr++)
                myout<<*ditr<<endl;
        }
    
        bool Parse(char* filename){
            if(filename == NULL) return false;
            ifstream myin(filename,ios::in);
            bool flag = ParseLabel(myin,m_Header);
            if(!flag) return false;
            while(!myin.eof()){
                stMyDataLabel data;
                flag = ParseLabel(myin,data);
                m_Data.push_back(data);
            }
            return flag;
        }
    
        bool ParseLabel(istream& myin,stMyDataLabel& label){
            string str;
            bool flag = true;
            do{
                myin >> str;
                int sidx=0,eidx=0;
                sidx = str.find(m_StartLabel);
                eidx = str.find(m_EndLabel);
                if(sidx >= 0 && eidx >= 0 && eidx > sidx){//<lable> or </label>
                    if(str.at(sidx+1) != '/')//start of <label>
                    {
                        //string substr(int pos = 0,int n = npos) const;//返回pos开始的n个字符组成的字符串
                        bool isSub=false;
                        string lableName = str.substr(sidx+1,eidx-sidx-1);
                        if(label.Label != "") isSub = true;//start of subitem's <label>
    
                        //find </label>
                        int sidx2=0,eidx2=0;
                        sidx2 = str.rfind(m_StartLabel);
                        eidx2 = str.rfind(m_EndLabel);                
                        if(eidx != eidx2 && str.at(sidx2+1) == '/')//<label>content</label>, has </label>
                        {
                            string strelab = str.substr(sidx2+2,eidx2-sidx2-2);
                            if(strelab == lableName){
                                if(isSub){
                                    stMyDataLabel sublabel;
                                    sublabel.Label = lableName;
                                    sublabel.Content.clear();
                                    sublabel.Content.push_back( str.substr(eidx+1,sidx2-eidx-1) );
                                    label.SubItems.push_back(sublabel);
                                }
                                else{
                                    label.Label = lableName;
                                    label.Content.clear();
                                    label.Content.push_back( str.substr(eidx+1,sidx2-eidx-1) );
                                }
                                continue;
                            }
                            else{
                                return false;
                            }                        
                        }
                        else{
                            if(isSub){
                                stMyDataLabel sublabel;
                                sublabel.Label = lableName;
                                label.SubItems.push_back(sublabel);
                                int curIdx = label.SubItems.size()-1;
                                bool bres = ParseLabel(myin,label.SubItems.at(curIdx));
                                if(!bres) return false;//subitem format error
                                else continue;//
                            }
                            else
                                label.Label = lableName;
                        }
                    }
                    else{// </lable>
                        string elabel = str.substr(sidx+2,eidx-sidx-2);
                        if(elabel == label.Label){//end of this label
                            return true;
                        }
                        else{//format error
                            return false;
                        }
                    }
                }
                else{//content
                    if(label.Label == "data" || label.Label == "DATA"){//data block
                        // 判断字符串是不是数字
                        stringstream sin(str);
                        float val;
                        if(!(sin >> val))//不是数字
                            label.Content.push_back(str);
                        else
                            label.Values.push_back(val);
                    }
                    else//header
                    {
                        int idx = str.find('=');
                        if(idx >= 0){//key=value
                            string strkey = str.substr(0,idx);
                            string strval = str.substr(idx+1);
                            label.KeyVal.insert(make_pair(strkey,strval));
                        }
                        else{
                            label.Content.push_back(str);
                        }
                    }
                }
            }while(flag);        
        }
        // 判断字符串是不是数字
        bool isNum(string str)
        {
            stringstream sin(str);
            double d;
            char c;
            if(!(sin >> d))
                return false;
            if (sin >> c)
                return false;
            return true;
        }
    };
    
    /*file format2:
    #xtype
    //comment
    [condition]
        项1=值1
        项2=值2
    [/condition]
    [mea]
        key3=value3
        key4=value4
    [/mea]
    [data]
    phi rcs ang
    1    1    1
    2    2    2
    [/data]
    */
    class MyDataParse2{//数据类型2的解析类
    public:
        stMyDataLabel m_Data;//single root
        char m_StartLabel;
        char m_EndLabel;
    public:
        MyDataParse2(){
            m_StartLabel = '[';
            m_EndLabel = ']';
        }
        void Init(){
            m_Data.Clear();
        }
    
        void Print(ostream& myout){
            myout<<m_Data;
        }
    
        bool Parse(char* filename){
            if(filename == NULL) return false;
            ifstream myin(filename,ios::in);
            string str;
            myin>>str;
            if(str.at(0) == '#'){
                m_Data.Label = str.substr(1);
            }
            bool flag = true;
            while(!myin.eof() && flag){
                flag = ParseLabel(myin,m_Data);
            }
            return flag;
        }
    
        bool ParseLabel(istream& myin,stMyDataLabel& label){
            string str;
            bool flag = true;
            do{
                myin >> str;
                if(str.substr(0,2) == "//")//comment,skip
                    continue;
    
                int sidx=0,eidx=0;
                sidx = str.find(m_StartLabel);
                eidx = str.find(m_EndLabel);
                if(sidx >= 0 && eidx >= 0 && eidx > sidx){//[lable] or [/label]
                    if(str.at(sidx+1) != '/')//start of <label>
                    {
                        //string substr(int pos = 0,int n = npos) const;//返回pos开始的n个字符组成的字符串
                        bool isSub=false;
                        string lableName = str.substr(sidx+1,eidx-sidx-1);
                        if(label.Label != "") isSub = true;//start of subitem's [label]
    
                        if(isSub){
                            stMyDataLabel sublabel;
                            sublabel.Label = lableName;
                            label.SubItems.push_back(sublabel);
                            int curIdx = label.SubItems.size()-1;
                            bool bres = ParseLabel(myin,label.SubItems.at(curIdx));
                            if(!bres) return false;//subitem format error
                            else continue;//
                        }
                        else
                            label.Label = lableName;
                    }
                    else{// </lable>
                        string elabel = str.substr(sidx+2,eidx-sidx-2);
                        if(elabel == label.Label){//end of this label
                            return true;
                        }
                        else{//format error
                            return false;
                        }
                    }
                }
                else{//content
                    if(label.Label == "data" || label.Label == "DATA"){//data block
                        // 判断字符串是不是数字
                        stringstream sin(str);
                        float val;
                        if(!(sin >> val))//不是数字
                            label.Content.push_back(str);
                        else
                            label.Values.push_back(val);
                    }
                    else//header
                    {
                        int idx = str.find('=');
                        if(idx >= 0){//key=value
                            string strkey = str.substr(0,idx);
                            string strval = str.substr(idx+1);
                            label.KeyVal.insert(make_pair(strkey,strval));
                        }
                        else{
                            label.Content.push_back(str);
                        }
                    }
                }
            }while(!myin.eof());        
        }
    };
    #endif

    测试(命令行方式)

    MyDataParse parse;
    parse.Init();
    parse.Parse("test.txt");//待解析的数据文件
    parse.Print(cout);

     测试数据:

    //test11.txt
    <head>
        <type>xtype</type>
        <condition>
            key1=value1
            key2=value2
        </condition>
        <mea>
            key3=value3
            key4=value4
        </mea>
    </head>
    <data>
    phi rcs ang
    1    2    3
    2    3    4
    </data>
    <data>
    phi rcs ang
    3    4    5
    4    5    6
    </data>
    //test12.txt
    <head>
        <type>xtype</type>
        <condition>
            key1=value1
            key2=value2
        </condition>
        <group>
            <part1>
                key3=value3
                key4=value4
            </part1>
            <part2>
                key3=value3
                key4=value4
            </part2>
        </group>
    </head>
    <data>
    phi rcs ang
    1    2    3
    2    3    4
    </data>
    <data>
    phi rcs ang
    3    4    5
    4    5    6
    </data>
    //test21.txt
    #xtype
    //comment
    [condition]
        项1=值1
        项2=值2
    [/condition]
    [mea]
        key3=value3
        key4=value4
    [/mea]
    [data]
    phi rcs ang
    1    1    1
    2    2    2
    [/data]
    [data]
    phi rcs ang
    3    1    1
    4    2    2
    [/data]
    //test22.txt
    #xtype
    //comment
    [condition]
        项1=值1
        项2=值2
    [/condition]
    [group]
        [part1]
            key3=value3
        [/part1]
        [part2]
            key4=value4
            key5=value5
        [/part2]
    [/group]
    [data]
    phi rcs ang
    1    1    1
    2    2    2
    [/data]
    [data]
    phi rcs ang
    3    1    1
    4    2    2
    [/data]
  • 相关阅读:
    数据源与连接池
    JavaBean
    JSP隐含对象
    kibana 报错 FATAL ERROR: CALL_AND_RETRY_LAST Allocation failed
    JS中key-value存取
    JS判断数组中是否包含某个值
    数据库的事务
    net 查看版本号
    同行右边浮动
    CodeFirst
  • 原文地址:https://www.cnblogs.com/hikeepgoing/p/6287078.html
Copyright © 2011-2022 走看看