この種のデータのサンプル パーサー
public IEnumerable<Dictionary<string, string>> Parse(TextReader reader)
{
var state = new State { Handle = ExpectTableTitle };
return GenerateFrom(reader)
.Select(line => state.Handle(line.Split('\t'), state))
.Where(returnIt => returnIt)
.Select(returnIt => state.Row);
}
private bool ExpectTableTitle(string[] lineParts, State state)
{
if (lineParts[0] == "%T")
{
state.TableTitle = lineParts[1];
state.Handle = ExpectFieldNames;
}
else
{
Console.WriteLine("Expected %T but found '"+lineParts[0]+"'");
}
return false;
}
private bool ExpectFieldNames(string[] lineParts, State state)
{
if (lineParts[0] == "%F")
{
state.FieldNames = lineParts.Skip(1).ToArray();
state.Handle = ExpectRowOrTableTitle;
}
else
{
Console.WriteLine("Expected %F but found '" + lineParts[0] + "'");
}
return false;
}
private bool ExpectRowOrTableTitle(string[] lineParts, State state)
{
if (lineParts[0] == "%R")
{
state.Row = lineParts.Skip(1)
.Select((x, i) => new { Value = x, Index = i })
.ToDictionary(x => state.FieldNames[x.Index], x => x.Value);
state.Row.Add("_tableTitle",state.TableTitle);
return true;
}
return ExpectTableTitle(lineParts, state);
}
public class State
{
public string TableTitle;
public string[] FieldNames;
public Dictionary<string, string> Row;
public Func<string[], State, bool> Handle;
}
private static IEnumerable<string> GenerateFrom(TextReader reader)
{
string line;
while ((line = reader.ReadLine()) != null)
{
yield return line;
}
}
次に、結果の各 Dictionary を _tableTitle エントリに基づいてドメイン オブジェクトの 1 つに変換/マップします。
サンプル データを使用したテスト ハーネスを次に示します。ファイルから読み取るには、StringReader の代わりに StreamReader を渡します。
const string data = @"%T\tperson
%F\tid\tname\taddress\tcity
%R\t1\tBob\t999 Main St\tBurbank
%R\t2\tSara\t829 South st\tPasadena
%T\thouses
%F\tid\tpersonid\thousetype\tColor
%R\t25\t1\tHouse\tRed
%R\t26\t2\tcondo\tGreen";
var reader = new StringReader(data.Replace("\\t","\t"));
var rows = Parse(reader);
foreach (var row in rows)
{
foreach (var entry in row)
{
Console.Write(entry.Key);
Console.Write('\t');
Console.Write('=');
Console.Write('\t');
Console.Write(entry.Value);
Console.WriteLine();
}
Console.WriteLine();
}
出力:
id = 1
name = Bob
address = 999 Main St
city = Burbank
_tableTitle = person
id = 2
name = Sara
address = 829 South st
city = Pasadena
_tableTitle = person
id = 25
personid = 1
housetype = House
Color = Red
_tableTitle = houses
id = 26
personid = 2
housetype = condo
Color = Green
_tableTitle = houses