CSV数据交换格式
两个程序之间如何交换数据,用什么格式,常见的有CSV,XML,JSON。
1.CSV介绍
关于CSV的介绍请参考维基https://zh.wikipedia.org/wiki/%E9%80%97%E5%8F%B7%E5%88%86%E9%9A%94%E5%80%BC
2.CSV格式解码
解码函数
__Array* CSVParser::parse(const char* fileName)
{
auto sharedFileUtils = FileUtils::getInstance();
string pathKey = sharedFileUtils->fullPathForFilename(fileName);//转换为全路径
string content = sharedFileUtils->getStringFromFile(pathKey);//读取
__String* contentStr = __String::create(content);//std::string转换为_string格式
__Array* rows = contentStr->componentsSeparatedByString("\n");//以换行符为间隔读取
__Array* ret = __Array::createWithCapacity(rows->count());
Ref *obj = nullptr;
CCARRAY_FOREACH(rows, obj)//遍历rows
{
auto fieldStr = static_cast<__String*>(obj);
__Array* fields = fieldStr->componentsSeparatedByString(",");//以逗号为间隔读取
ret->addObject(fields);
}
return ret;
}
记事本格式
读取完输出
XML数据交换格式
1.XML格式 https://zh.wikipedia.org/wiki/XML
2.解析
目前流行的主要有SAX和DOM。
2.1 SAX解析
SAX是一种基于事件驱动的解析方式。从上到下读取文档,但无法写入,且程序编写有点难度,有点就是速度快
例子:
通过下面几个函数可以实现读取XML文件
private:
std::string startElementName;//记录开始元素
cocos2d::ValueMap row;
public:
static XmlParser * createWithFile(const char *fileName);
bool initWithFile(const char* xmlName);
//SAXDelegator 的3个回调方法
virtual void startElement(void *ctx, const char *name, const char **atts);
virtual void endElement(void *ctx, const char *name);
virtual void textHandler(void *ctx, const char *ch, int len);
2.2 DOM解析
DOM称为文档对象模型,DOM模型是将XML文档作为树状结构进行分析。
虽然因为一次性读入内存导致解析速度变慢,但缺可以修改XML文档。
COCOS封装了XML解析库tinyxml2.是基于C++语言的DOM函数的解析库,可以读写XML文档。
主要函数parse(),解析XML数据
void XmlParser::parse()
{
tinyxml2::XMLDocument xmlDoc;
xmlDoc.Parse(content.c_str());
tinyxml2::XMLElement *root = xmlDoc.RootElement();
tinyxml2::XMLElement *note =root->FirstChildElement("Note");
while(note){
row = ValueMap();
//取id属性
const tinyxml2::XMLAttribute *att = note->FirstAttribute();
std::pair<std::string,Value> idPair("id",Value(att->Value()));
row.insert(idPair);
//取CDate元素内容
tinyxml2::XMLElement *dateElement =note->FirstChildElement("CDate");
row["CDate"] = Value(dateElement->GetText());
//取Content元素内容
tinyxml2::XMLElement *contentElement =note->FirstChildElement("Content");
row["Content"] = Value(contentElement->GetText());
//取UserID元素内容
tinyxml2::XMLElement *userIDElement =note->FirstChildElement("UserID");
row["UserID"] = Value(userIDElement->GetText());
list.push_back(Value(row));
if(note->NextSibling() == nullptr){
break;
}else {
note = note->NextSibling()->ToElement();
}
}
}
再输出
JSON数据交换格式
格式如图
1.1 rapidjson解码
解码函数decode
void JsonParser::decode()
{
rapidjson::Document document;
document.Parse<0>(content.c_str());
//解析错误
CCASSERT(!document.HasParseError(), "Parsing to document failure.");
log("Parsing to document succeeded.");
CC_ASSERT(document.IsObject() && document.HasMember("Record"));
const rapidjson::Value &records= document["Record"]; //读取中文的数组
//判断是不是数组
CC_ASSERT(records.IsArray());
for(unsigned int i = 0; i < records.Size();i++) //如果不是数组,这一行会报错
{
row = ValueMap();
//获得一条记录对象
const rapidjson::Value &record = records[i];
//判断这个record有没有ID键
CC_ASSERT(record.HasMember("ID"));
const rapidjson::Value &val_id = record["ID"];
//判断ID类型
CC_ASSERT(val_id.IsString());
row["id"] = Value(val_id.GetString());
//判断这个record有没有CDate键
CC_ASSERT(record.HasMember("CDate"));
const rapidjson::Value &val_CDate = record["CDate"];
//判断CDate类型
CC_ASSERT(val_CDate.IsString());
row["CDate"] = Value(val_CDate.GetString());
//判断这个record有没有Content键
CC_ASSERT(record.HasMember("Content"));
const rapidjson::Value &val_Content = record["Content"];
//判断Content类型
CC_ASSERT(val_Content.IsString());
row["Content"] = Value(val_Content.GetString());
//判断这个record有没有UserID键
CC_ASSERT(record.HasMember("UserID"));
const rapidjson::Value &val_UserID = record["UserID"];
//判断UserID类型
CC_ASSERT(val_UserID.IsString());
row["UserID"] = Value(val_UserID.GetString());
list.push_back(Value(row));
}
}
1.2 rapidjson编码
ValueVector listData ;
auto createValueMap1 =[&](){
ValueMap ret;
ret["ID"] = Value(1);
ret["CDate"] = Value("2014-3-10");
ret["Content"] = "发布iOSBook0";
ret["UserID"] = "tony";
return ret;
};
listData.push_back(Value(createValueMap1()));
auto createValueMap2 =[&](){
ValueMap ret;
ret["ID"] = Value(2);
ret["CDate"] = Value("2014-3-11");
ret["Content"] = "发布iOSBook1";
ret["UserID"] = "tony";
return ret;
};
listData.push_back(Value(createValueMap2()));
auto createValueMap3 =[&](){
ValueMap ret;
ret["ID"] = Value(3);
ret["CDate"] = Value("2014-3-12");
ret["Content"] = "发布iOSBook2";
ret["UserID"] = "tony";
return ret;
};
listData.push_back(Value(createValueMap3()));
auto createValueMap4 =[&](){
ValueMap ret;
ret["ID"] = Value(4);
ret["CDate"] = Value("2014-3-13");
ret["Content"] = "发布iOSBook3";
ret["UserID"] = "tony";
return ret;
};
listData.push_back(Value(createValueMap4()));
auto createValueMap5 =[&](){
ValueMap ret;
ret["ID"] = Value(5);
ret["CDate"] = Value("2014-3-14");
ret["Content"] = "发布iOSBook4";
ret["UserID"] = "tony";
return ret;
};
listData.push_back(Value(createValueMap5()));
auto createValueMap6 =[&](){
ValueMap ret;
ret["ID"] = Value(6);
ret["CDate"] = Value("2014-3-15");
ret["Content"] = "发布iOSBook5";
ret["UserID"] = "tony";
return ret;
};
listData.push_back(Value(createValueMap6()));
auto parser = JsonParser::createWithArray(listData);//加入数据
parser->encode();//编码
void JsonParser::encode()
{
rapidjson::Document document;
document.SetObject();
rapidjson::Document::AllocatorType& allocator = document.GetAllocator();
rapidjson::Value array(rapidjson::kArrayType);
for (auto& v: listData)
{
ValueMap row = v.asValueMap();
rapidjson::Value object(rapidjson::kObjectType);
rapidjson::Value v_id;
v_id.SetString(row["ID"].asString().c_str(), allocator);
object.AddMember("ID", v_id, allocator);
rapidjson::Value v_Date;
v_Date.SetString(row["CDate"].asString().c_str(), allocator);
object.AddMember("CDate", v_Date, allocator);
rapidjson::Value v_Content;
v_Content.SetString(row["Content"].asString().c_str(), allocator);
object.AddMember("Content", v_Content, allocator);
rapidjson::Value v_UserID;
v_UserID.SetString(row["UserID"].asString().c_str(), allocator);
object.AddMember("UserID", v_UserID, allocator);
array.PushBack(object, allocator);
}
document.AddMember("ResultCode", 0, allocator);
document.AddMember("Record", array, allocator);
rapidjson::StringBuffer buffer;
rapidjson::Writer<rapidjson::StringBuffer> writer(buffer);
document.Accept(writer);
auto out = buffer.GetString();
log("out: %s", out);
}