Обработка NEWLINE в DelimitedRecord с помощью Filehelpers

Я использую отличную библиотеку FileHelpers для анализа ряда различных файлов. В одном из этих файлов есть (некоторые) строки, которые выглядят так

id|name|comments|date
01|edov|bla bla bla bla|2012-01-01
02|john|bla bla bla bla|2012-01-02
03|Pete|bla bla <NEWLINE>
bla bla|2012-03-01
04|Mary|bla bla bla bla|2012-01-01

Обратите внимание, что строка с идентификатором 3 имеет новую строку в тексте. Также обратите внимание, что комментарии не заключены в кавычки, поэтому [FieldQuoted('"', MultilineMode.AllowForRead)] меня не спасет.

Filehelpers выдает исключение в строке 4:

Разделитель '|' не найдено после поля «комментарии» (в записи меньше полей, неправильный разделитель или следующее поле должно быть помечено как необязательное).

Могу ли я в любом случае разобрать этот файл с помощью FileHelpers?


person edosoft    schedule 16.07.2012    source источник


Ответы (1)


Вы должны исправить ввод, добавив кавычки в третье поле, прежде чем передать его механизму FileHelpers. Это легко сделать с помощью LINQ, как показано в следующей программе.

[DelimitedRecord("|")]
[IgnoreFirst(1)]
public class ImportRecord
{
    public string Id;
    public string Name;
    [FieldQuoted(QuoteMode.AlwaysQuoted, MultilineMode.AllowForRead)]
    public string Comments;
    public string Date;
}

class Program
{
    static void Main(string[] args)
    {
        var engine = new FileHelperEngine<ImportRecord>();

        string input = "id|name|comments|date" + Environment.NewLine +
                              "01|edov|bla bla bla bla|2012-01-01" + Environment.NewLine +
                              "02|john|bla bla bla bla|2012-01-02" + Environment.NewLine +
                              "03|Pete|bla bla" + Environment.NewLine +
                              "bla bla|2012-03-01" + Environment.NewLine +
                              "04|Mary|bla bla bla bla|2012-01-01";

        // Modify import to add quotes to multiline fields
        var inputSplitAtSeparator = input.Split('|');
        // Add quotes around the field after every third '|'
        var inputWithQuotesAroundCommentsField = inputSplitAtSeparator.Select((x, i) => (i % 3 == 2) ? "\"" + x + "\"" : x);
        var inputJoinedBackTogether = String.Join("|", inputWithQuotesAroundCommentsField);

        ImportRecord[] validRecords = engine.ReadString(inputJoinedBackTogether);

        // Check the third record
        Assert.AreEqual("03", validRecords[2].Id);
        Assert.AreEqual("Pete", validRecords[2].Name);
        Assert.AreEqual("bla bla" + Environment.NewLine + "bla bla", validRecords[2].Comments);
        Assert.AreEqual("2012-03-01", validRecords[2].Date);

        Console.WriteLine("All assertions passed");
        Console.ReadKey();
    }
}
person shamp00    schedule 20.07.2012
comment
Спасибо, интересное решение - person edosoft; 03.12.2012
comment
к сожалению, это не решает проблему для всего файла с более чем одной записью... - person Jan; 22.05.2014
comment
@Jan Ян, конечно, это так ... пример кода проверяет третью запись validRecords[2]. - person shamp00; 22.05.2014
comment
@ shamp00, извините, вы правы. Я должен был присмотреться к вашему примеру кода :) - person Jan; 22.05.2014