需要解析一种类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 </data>
<data>
phi rcs ang </data>
数据格式2:
#xtype
//comment
[condition]
项1=值1
项2=值2
[/condition]
[mea]
key3=value3
key4=value4
[/mea]
[data]
phi rcs ang [/data]
[data]
phi rcs ang [/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<<"\t"<<*sitr<<"\t";
}
myout<<endl;
for (auto mitr = m_Data.KeyVal.begin(); mitr != m_Data.KeyVal.end(); mitr++)
{
myout<<"\t"<<mitr->first<<" = "<<mitr->second<<"\t";
}
myout<<endl; int dsize = m_Data.Content.size();
int curdidx = ;
for(vector<float>::iterator fitr = m_Data.Values.begin(); fitr != m_Data.Values.end(); fitr++){
myout<<"\t"<<*fitr<<"\t";
curdidx++;
if(curdidx >= dsize){
cout<<endl;
curdidx=;
}
}
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=,eidx=;
sidx = str.find(m_StartLabel);
eidx = str.find(m_EndLabel);
if(sidx >= && eidx >= && eidx > sidx){//<lable> or </label>
if(str.at(sidx+) != '/')//start of <label>
{
//string substr(int pos = 0,int n = npos) const;//返回pos开始的n个字符组成的字符串
bool isSub=false;
string lableName = str.substr(sidx+,eidx-sidx-);
if(label.Label != "") isSub = true;//start of subitem's <label> //find </label>
int sidx2=,eidx2=;
sidx2 = str.rfind(m_StartLabel);
eidx2 = str.rfind(m_EndLabel);
if(eidx != eidx2 && str.at(sidx2+) == '/')//<label>content</label>, has </label>
{
string strelab = str.substr(sidx2+,eidx2-sidx2-);
if(strelab == lableName){
if(isSub){
stMyDataLabel sublabel;
sublabel.Label = lableName;
sublabel.Content.clear();
sublabel.Content.push_back( str.substr(eidx+,sidx2-eidx-) );
label.SubItems.push_back(sublabel);
}
else{
label.Label = lableName;
label.Content.clear();
label.Content.push_back( str.substr(eidx+,sidx2-eidx-) );
}
continue;
}
else{
return false;
}
}
else{
if(isSub){
stMyDataLabel sublabel;
sublabel.Label = lableName;
label.SubItems.push_back(sublabel);
int curIdx = label.SubItems.size()-;
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+,eidx-sidx-);
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 >= ){//key=value
string strkey = str.substr(,idx);
string strval = str.substr(idx+);
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() == '#'){
m_Data.Label = str.substr();
}
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(,) == "//")//comment,skip
continue; int sidx=,eidx=;
sidx = str.find(m_StartLabel);
eidx = str.find(m_EndLabel);
if(sidx >= && eidx >= && eidx > sidx){//[lable] or [/label]
if(str.at(sidx+) != '/')//start of <label>
{
//string substr(int pos = 0,int n = npos) const;//返回pos开始的n个字符组成的字符串
bool isSub=false;
string lableName = str.substr(sidx+,eidx-sidx-);
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()-;
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+,eidx-sidx-);
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 >= ){//key=value
string strkey = str.substr(,idx);
string strval = str.substr(idx+);
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 </data>
<data>
phi rcs ang </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 </data>
<data>
phi rcs ang </data>
//test21.txt
#xtype
//comment
[condition]
项1=值1
项2=值2
[/condition]
[mea]
key3=value3
key4=value4
[/mea]
[data]
phi rcs ang [/data]
[data]
phi rcs ang [/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 [/data]
[data]
phi rcs ang [/data]

类xml数据格式解析的更多相关文章

  1. [ java 工具类] xml字符串解析成Map(DOM解析)

    package com.tencent.jungle.wechat.util; import com.google.inject.Singleton; import org.w3c.dom.Docum ...

  2. iOS-数据持久化基础-JSON与XML数据解析

    解析的基本概念 所谓“解析”:从事先规定好的格式串中提取数据 解析的前提:提前约定好格式.数据提供方按照格式提供数据.数据获取方按照格式获取数据 iOS开发常见的解析:XML解析.JSON解析 一.X ...

  3. iOS 阶段学习第23天笔记(XML数据格式介绍)

    iOS学习(OC语言)知识点整理 一.XML数据格式介绍 1)概念:xml是extensible markup language扩展的标记语言,一般用来表示.传输和存储数据 2)xml与json目前使 ...

  4. iOS - XML 数据解析

    前言 @interface NSXMLParser : NSObject public class NSXMLParser : NSObject 1.XML 数据 XML(Extensible Mar ...

  5. UI学习笔记---第十六天XML JSON解析

    一.解析的基本概念 从事先规定好的格式中提取数据 解析的前提:提前约定好格式.数据提供方按照格式提供数据,数据方按照格式获取数据 常见解析方式XML解析JSON解析 二.XML:可扩展标记语言 XML ...

  6. 玩转iOS开发 - JSON 和 Xml 数据解析

    前言 Json 和xml是网络开发中经常使用的数据格式,JSON轻量级.xml相对较复杂.所以如今用JSON的比例很大.基本上从server获取的返回数据都是JSON格式的,作为iOS开发人员,解析J ...

  7. 关于C#对Xml数据解析

    首先进行简单说明Xml 与Html  和 XAML数据标签的差别. 1.Xml属于数据文本, 被设计为传输和存储数据,其焦点是数据的内容.它与json格式数据相似,可作为服务数据传输类型. 其中XML ...

  8. 通过正则表达式实现简单xml文件解析

    这是我通过正则表达式实现的xml文件解析工具,有些XHTML文件中包含特殊符号,暂时还无法正常使用. 设计思路:常见的xml文件都是单根树结构,工具的目的是通过递归的方式将整个文档树装载进一个Node ...

  9. JAVA 中XML的解析

    XML:  可扩展标记语言(extensible Markup Language) 用于标记电子文件使其具有结构性的标记语言.XML可以用来标记数据.定义数据类型,是一种允许用户对自己的标记语言进行定 ...

随机推荐

  1. IE低版本下实现html5的placeholder(表单提示)功能

    placeholder 属性提供可描述输入字段预期值的提示信息(hint). 该提示会在输入字段为空时显示,并会在字段获得焦点时消失. 注释:placeholder 属性适用于以下的 <inpu ...

  2. 异步陷阱之IO

    异步陷阱之IO篇 很多教程和资料都强调流畅的用户体验需要异步来辅助,核心思想就是保证用户前端的交互永远有最高的优先级,让一切费时的逻辑通通放到后台,等到诸事完备,通知一下前端给个提示或者继续下一步.随 ...

  3. IE6浏览器不支持固定定位(position:fixed)解决方案

    代码如下: <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w ...

  4. 24个JavaScript初学者最佳实践

    这里面说到的一个就是使用循环新建一个字符串时,用到了join(),这个比较高效,常常会随着push(); 绑定某个动作时,可以把要执行的绑定内容定义为一个函数,然后再执行.这样做的好处有很多.第一是可 ...

  5. mvc4中jquery-ui日期控件datepicker的应用

    mvc4中jquery-ui日期控件datepicker的应用 本文适合mvc中日期选择需要的同学: 假设读者已经具备了mvc4和javascript中的相关知识 一. 开始项目之前把项目中目录:/C ...

  6. GridView使用技巧

    http://yushuir.blog.163.com/blog/static/4346713820081023103937681/

  7. poj3519 Lucky Coins Sequence矩阵快速幂

    Lucky Coins Sequence Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others ...

  8. 【欧拉计划4】Largest palindrome product

    欢迎访问我的新博客:http://www.milkcu.com/blog/ 原文地址:http://www.milkcu.com/blog/archives/1371281760.html 原创:[欧 ...

  9. .NET软件开发资源

    .NET软件开发资源 最近建了一个.NET软件开发资源的360网盘共享群,把收集的一些.NET软件开发资源分享给大家,也欢迎大家把好的东东分享一下. 资源主要有:开发工具.控件资源.书籍教程.网页设计 ...

  10. C#中另辟蹊径解决JSON / XML互转的问题

    C#中另辟蹊径解决JSON / XML互转的问题 最近在一个POC的项目中要用到JSON和XML的相互转换, 虽然我知道很多类库如JSON.NET具备这种功能, 但是我还是另辟蹊径的使用Spider ...