想象一下,您在 CSV 文件中有一个具有这种布局的表格:
名称,property1 [unit1],property2 [unit2] 名称1,4.5,2.3 名称2,3.2,7.4 名称3,5.5,6.1
我需要将每一行转换为这种 JSON 结构(即,对于第 1 行):
{
"name1": [
{
"properties": [
{
"property_1": "_value_",
"unit": "unit1"
},
{
"property_2": "_value_",
"unit": "unit2"
}
]
}
]
}
最重要的是,我必须解释我使用的是 Qt 4.7 并且无法更新;另外,我无法安装 Qxt,所以我依赖qt-json进行 JSON 解析/编码。此外,CSV 文件不是由我创建/维护的,所以我也无法真正更改它。
所以有了这一切,我意识到我需要一些东西,所以这是一个多重问题:
- 我应该如何编写正则表达式来读取每列标题中的单位?请注意,单位括在右括号中。
- 想象一下,我将标题行和其他行都提取到 a
QList<QString>
中,将每一列分隔为一个字符串。我如何设法同步所有数据位以便在 QString 上创建我需要的 JSON 结构?(我想我需要它在 QString 中,所以我可以将每一行转储到不同的文件中,但我也对其他选项持开放态度)
最后一点 - 我还需要它具有一定的可扩展性。将应用它的 CSV 文件的列数非常不同:有些有 8 列,有些有 20 列。
我知道发布“多问题”不是一个好习惯,但问题是我对这一切感到不知所措,而且因为我几乎没有使用 Qt 的经验,我什至无法定义一个计划来解决这个问题. 希望有人可以分享一些指针。谢谢!
编辑 所以,我一直在思考这个问题,我实际上不知道这是否是一个好主意/可行,但这是我的想法:
- 浏览标题行时,我会检查每个列字符串是否对 RegEx 有影响。如果是这样,我会将列索引和单位字符串存储在一个列表中;
- 然后,在遍历其他行时,为了将它们解析为 JSON,我将检查每一列是否与上一个列表中的索引匹配,如果是,我会将单元添加到地图中(如 qt- json 文档解释)
这有道理吗?任何人都可以模拟一个我可以为此工作的骨架吗?
编辑2
到目前为止,我已经设法完成了一些工作,但仍然无法正常工作。现在我已经设法从 CSV 文件中正确读取,但输出不正确。任何人都可以分享一些见解吗?
注意:processLineFromCSV函数返回一个获得的 QStringList,如下所示:QStringList cells = line.split(separator_char);
注2:正则表达式是从这个答案中获得的。
注意3:检查下面我得到的输出类型。现在我认为这个问题更多地与qt-json
lib 的使用有关,而不是与代码的其余部分有关,但欢迎任何帮助!:)
到目前为止的代码:
QFile file(csvfile);
if (file.open(QIODevice::ReadOnly | QIODevice::Text))
{
bool first = true;
QVariantMap map;
QVariantMap propertyMap;
QList<QVariant> generalList, propertiesList;
while (!file.atEnd())
{
QString line = file.readLine();
if(first == true){
headerList = processLineFromCSV(line, separator_char);
first = false;
}else{
QStringList cellList = processLineFromCSV(line, separator_char);
int i=0;
for(i; i<cellList.size(); i++)
{
// check the header cell for "[unit]" string
// returns -1 if does not have the string
// if it has the string, it's stored in capturedUnits[1]
int test = exp.indexIn(headerList.at(i));
// store the captured units in a QStringList
QStringList capturedUnits = exp.capturedTexts();
if(test==-1){ // if header does not have a captured unit - general column
QString name = headerList.at(i);
QString sanitizeName= name.remove(exp.capturedTexts().at(0), Qt::CaseSensitive);
map[sanitizeName] = cellList.at(i);
}
else{ // if header string has a captured unit - property column
QString propertyName = headerList.at(i); // extract string in header
QString sanitizedPropertyName = propertyName.remove(exp); //remove the unit regex from the string
sanitizedPropertyName.remove(QChar('\n'), Qt::CaseSensitive); // clear newlines
if(sanitizedPropertyName.startsWith('"') && sanitizedPropertyName.endsWith('"'))
{
sanitizedPropertyName.remove(0,1);
sanitizedPropertyName.remove(sanitizedPropertyName.length(),1);
}
QString value =cellList.at(i); // extract string in value
QString sanitizedValue = value.remove(QChar('\n'), Qt::CaseSensitive); // clear newlines
if(sanitizedValue.startsWith('"') && sanitizedValue.endsWith('"'))
{
sanitizedValue.remove(0,1);
sanitizedValue.remove(sanitizedValue.length(),1);
}
propertyMap[sanitizedPropertyName]= sanitizedValue; // map the property: value pair
propertyMap["unit"] = capturedUnits.at(1); // map the unit: [unit] value pair
QByteArray general = QtJson::serialize(map); // serialize the pair for general column
QByteArray properties = QtJson::serialize(propertyMap); // serialize the pair for property column
QVariant genVar(general);
QVariant propVar(properties);
generalList.append(genVar);
propertiesList.append(propVar);
}
}
}}
QByteArray finalGeneral = QtJson::serialize(generalList);
QByteArray finalProperties = QtJson::serialize(propertiesList);
qDebug() << finalGeneral;
qDebug() << finalProperties;
file.close();
}
输出:
"[
"{ \"name\" : \"name1\" }",
"{ \"name\" : \"name1\" }",
"{ \"name\" : \"name2\" }",
"{ \"name\" : \"name2\" }",
"{ \"name\" : \"name3\" }",
"{ \"name\" : \"name3\" }"
]"
"[
"{ \"property1 \" : \"4.5\", \"unit\" : \"unit1\" }",
"{ \"property1 \" : \"4.5\", \"property2 \" : \"2.3\", \"unit\" : \"unit2\" }",
"{ \"property1 \" : \"3.2\", \"property2 \" : \"2.3\", \"unit\" : \"unit1\" }",
"{ \"property1 \" : \"3.2\", \"property2 \" : \"7.4\", \"unit\" : \"unit2\" }",
"{ \"property1 \" : \"5.5\", \"property2 \" : \"7.4\", \"unit\" : \"unit1\" }",
"{ \"property1 \" : \"5.5\", \"property2 \" : \"6.1\", \"unit\" : \"unit2\" }"
]"