web-dev-qa-db-ja.com

ヘッダーにスペースが含まれているCSVをCsvHelperで解析します

フィールドヘッダー付きのCSVファイルがあり、スペースで区切られた2つまたは3つの単語が含まれているものがあります。

Screenshot of the first few rows of a spreadsheet in a spreadsheet application, including headers that contain spaces, as described above.

上の画像で、スペースを含むフィールドヘッダーを確認できます。
「時刻」、「プロセス名」、「画像パス」。

reader.GetRecords<DataRecord>();DataRecordは定義したクラス)を呼び出してCSVを読み取ろうとすると、次のエラーが発生します。

フィールド 'TimeOfDay'はCSVファイルに存在しません。 "*

これは、私のDataRecordクラスにスペースを含むメンバーを含めることができないためです。

CsvHelperを使用してCSVファイルを解析するにはどうすればよいですか?

20
E235

CsvHelper Documentation に基づいて、目的の結果を達成する方法はいくつかあります。

1。ヘッダーから空白を無視する(問題は簡単に解決できると思います)

CsvHelper 3以降では、PrepareHeaderForMatchhttp://joshclose.github.io/CsvHelper/configuration#headers に記載)を使用して、ヘッダーから空白を削除します。

csv.Configuration.PrepareHeaderForMatch =
    header => Regex.Replace(header, @"\s", string.Empty)

CsvHelper 2で、IgnoreHeaderWhiteSpaceフラグを設定します。これは、列を名前でプロパティに一致させるときに、ヘッダーの空白を無視するようにリーダーに指示します。

reader.Configuration.IgnoreHeaderWhiteSpace = true;

2。手動で読む

次のように、各フィールドを手動で読み取ることができます。

var reader = new CsvReader(sr);
do
{
    reader.Read();                   
    var record=new DataRecord();

    record.TimeOfDay=reader.GetField<string>("Time of Day");
    record.ProcessName=reader.GetField<string>("Process Name");
    record.PID=reader.GetField<string>("PID");
    record.Operation=reader.GetField<string>("Operation");
    record.Path=reader.GetField<string>("Path");
    record.Result=reader.GetField<string>("Result");
    record.Detail=reader.GetField<string>("Detail");
    record.ImagePath=reader.GetField<string>("Image Path");

} while (!reader.IsRecordEmpty());

3。クラスマッピング:

次のようにname class mappingを使用して、クラスのプロパティとCSVファイルの見出しを手動でマッピングできます。

public sealed class DataRecordMap:CsvClassMap<DataRecord>
{
    public DataRecordMap()
    {
         Map( m => m.TimeOfDay).Name("Time Of Day");
         Map( m => m.ProcessName).Name("Process Name");
         Map( m => m.PID).Name("PID");   
         Map( m => m.Operation).Name("Operation");    
         Map( m => m.Path).Name("Path");
         Map( m => m.Result).Name("Result");
         Map( m => m.Detail).Name("Detail");
         Map( m => m.ImagePath).Name("Image Path");
     }
}

次に、以下を使用して登録する必要があります。

reader.Configuration.RegisterClassMap<DataRecordMap>();
27
user3473830

ライブラリは 属性 をサポートするようになりました。 Name 属性を使用することをお勧めします。

public class DataRecord
{
    [Name("Time of Day")]
    public string TimeOfDay { get; set; }

    [Name("Process Name")]
    public string ProcessName { get; set; }

    public string PID { get; set; }
    public string Operation { get; set; }
    public string Path { get; set; }
    public string Result { get; set; }
    public string Detail { get; set; }

    [Name("Image Path")]
    public string ImagePath { get; set; }

    public static IEnumerable<DataRecord> ParseDataRecords(Stream file)
    {
        using (var sr = new StreamReader(file))
        using (var csv = new CsvReader(sr))
        {
            foreach (var record in csv.GetRecords<DataRecord>())
            {
                yield return record;
            }
        }
    }
}
4
JPK

マッピングを作成する必要があります http://joshclose.github.io/CsvHelper/mapping

0
Bruce Dunwiddie