2

次のようなレイアウトの CSV ファイルにテーブルがあるとします。

名前,プロパティ1 [ユニット1],プロパティ2 [ユニット2]
name1,4.5,2.3
name2,3.2,7.4
name3,5.5,6.1

各行をこの種の JSON 構造 (つまり、行 1) に変換する必要があります。

{
    "name1": [
        {
            "properties": [
                {
                    "property_1": "_value_",
                    "unit": "unit1"
                },
                {
                    "property_2": "_value_",
                    "unit": "unit2"
                }
            ]
        }
    ]
}

さらに、Qt 4.7 を使用していて更新できないことを説明しなければなりません。また、Qxt をインストールできないため、JSON の解析/エンコードにはqt-jsonを使用しています。さらに、CSVファイルは私が作成/管理していないため、実際に変更することもできません。

以上のことから、いくつか必要なことに気付きました。これは一種の複数の質問です。

  • 各列のヘッダーの単位を読み取るには、正規表現をどのように記述すればよいですか? 単位は正括弧で囲まれていることに注意してください。
  • ヘッダー行と他の行の両方を に抽出し、QList<QString>各列を文字列として分離すると想像してください。QString で必要な JSON 構造を作成するために、データのすべてのビットを同期するにはどうすればよいですか? (QStringで必要だと思うので、各行を別のファイルにダンプできますが、他のオプションも利用できます)

最後に 1 つだけ注意してください。ある程度拡張性を持たせるためにも、これが必要です。これが適用される CSV ファイルは、列数が非常に多様です。8 列のものもあれば、20 列のものもあります。

「複数の質問」を投稿するのは良い習慣ではないことはわかっていますが、これらすべてに圧倒されすぎており、Qt の経験がほとんどないため、これを攻撃する計画を定義することさえできません。 . 誰かがいくつかの指針を共有できることを願っています。ありがとう!

編集 だから、私はこれについてもう少し考えてきましたが、これが良い考え/実行可能かどうかは実際にはわかりませんが、ここに私が考えたことがあります:

  • ヘッダー行を調べるとき、各列の文字列に正規表現のヒットがあるかどうかを確認します。その場合、列のインデックスと単位文字列をリストに格納します。
  • 次に、他の行を調べて JSON に解析するために、各列が前のリストのインデックスと一致するかどうかを確認し、一致する場合は、ユニットをマップに追加します (qt- json ドキュメントで説明しています)

これは意味がありますか?これに取り組むことができるスケルトンを誰かがモックアップできますか?

EDIT2

これまでのところ、いくつかのことが機能するようになりましたが、まだ正常に機能していません。現在、CSV ファイルから正しく読み取ることができましたが、出力が正しく出力されません。誰でもいくつかの洞察を共有できますか?

注: processLineFromCSV関数は、次のように取得した QStringList を返します。QStringList cells = line.split(separator_char);

注2:正規表現はこの回答から取得されました。

注3:取得している出力のタイプについては、以下を確認してください。今のところ、問題qt-jsonは実際にはコードの残りの部分よりもライブラリの使用に関連していると思いますが、どんな助けも大歓迎です! :)

これまでのコード:

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\" }"
]"
4

3 に答える 3

1

ExplodingRat による回答を使用すると、これが最終的なコードです: (最後にファイルを作成せずに)

QString csvfile = ui->lineEditCSVfile->text();
    QString separator_char = ui->lineEditSeparator->text();
    QRegExp exp("\\[([^\\]]+)\\]");

    QFile file(csvfile);
     if (!file.open(QIODevice::ReadOnly | QIODevice::Text))
         return;

    QString csv = file.readAll();

    QStringList csvRows = csv.split('\n', QString::SkipEmptyParts);

    QStringList csvHeader = csvRows.takeFirst().split(separator_char);

    csvHeader.removeFirst();

    foreach(QString row, csvRows) {
        QStringList values = row.split(separator_char);

        QString rowName = values.takeFirst();

        QVariantList general;
        QVariantList properties;
        for(int i = 0; i < values.size(); i++) {
            QString value = values[i];

            int test = exp.indexIn(csvHeader[i]);
            //qDebug() << test;

            //qDebug() << csvHeader;
            QStringList capturedUnits = exp.capturedTexts();
            QString propName = csvHeader[i];


            if(test==-1){
                //QString propName = csvHeader[i].remove(exp);
                //qDebug() <<"property name" << propName;

                QVariantMap property;
                property[propName] = value;
                general.append(property);
            }else{
                propName.remove(exp);
                //QStringList propParts = csvHeader[i].split(' ');
                //QString propName = csvHeader[i].remove(exp);
                QString propType = capturedUnits[1];

                QVariantMap property;
                property[propName] = value;
                property["unit"] = propType;

                properties.append(property);
            }
        }

        QVariantMap propertyObj;
        propertyObj["properties"] = properties;
        QVariantList propList;
        propList.append(propertyObj);

        QVariantMap generalObj;
        generalObj["general"] = general;
        QVariantList generalList;
        generalList.append(generalObj);

        QVariantList fullList;
        fullList.append(generalObj);
        fullList.append(propertyObj);

        QVariantMap root;
        root[rowName] = fullList;

        QByteArray json = QtJson::serialize(root);

        json.prepend('[');
        json.append(']');

        qDebug() << json;

        // Now you can save json to a file
于 2013-06-13T10:07:18.100 に答える
1

これはあなたにとって良いスタートになるはずです:

QString csv = "name,property1 [unit1],property2 [unit2],property3 [unit3]\n"
              "name1,4.5,2.3\n"
              "name2,3.2,7.4\n"
              "name3,5.5,6.1,4.3\n";

QStringList csvRows = csv.split('\n', QString::SkipEmptyParts);
QStringList csvHeader = csvRows.takeFirst().split(',');
csvHeader.removeFirst();

foreach(QString row, csvRows) {
    QStringList values = row.split(',');
    QString rowName = values.takeFirst();

    QVariantList properties;
    for(int i = 0; i < values.size(); i++) {
        QString value = values[i];
        QStringList propParts = csvHeader[i].split(' ');
        QString propName = propParts[0];
        QString propType = propParts[1].mid(1, propParts[1].size() - 2);

        QVariantMap property;
        property[propName] = value;
        property["unit"] = propType;

        properties.append(property);
    }

    QVariantMap propertyObj;
    propertyObj["properties"] = properties;
    QVariantList propList;
    propList.append(propertyObj);

    QVariantMap root;
    root[rowName] = propList;

    QByteArray json = QtJson::serialize(root);
    qDebug() << json;

    // Now you can save json to a file
}
于 2013-06-12T15:11:01.630 に答える