c# - FileHelper 在 CSV 中读取,其中初始行指定列名
问题描述
对于上下文,我正在尝试解析 7dtd 本地化文件。该文件的内容类似于以下内容:
Key,File,Type,UsedInMainMenu,NoTranslate,english,Context / Alternate Text,german,latam,french,italian,japanese,koreana,polish,brazilian,russian,turkish,schinese,tchinese,spanish
meleeToolCrowbar,items,Tool,,,Crowbar,,,,,,,,,,,,,,
问题是,呈现的数据顺序因文件而异,其中第一行指定文件中每个条目的项目位置。我需要读入这个文件并将其与多个其他类似结构的文件合并。
我最初尝试只读入并使用逗号上的拆分字符串进行解析,但是有些字段中可能有逗号(以引号为界)。因此,当我开始研究潜在的解决方案时,FileHelpers 出现了。但是,据我所知,这使用静态列来定义属性,这不适用于我的上下文,因为 a) 列的顺序不同,b) 并非所有列都存在。
任何帮助找到解决方案将不胜感激。
解决方案
如果您查看库的动态ClassBuilder部分,您可以通过添加字段来创建一个在列和您想要的类之间映射的类。然后使用CreateRecordClass对象创建运行时引擎要使用的实际类类型。
您需要解析第一行,然后计算出您拥有的列。如果您不指定任何列或类型,我相信您可以使用分隔引擎为您完成这项工作。
使用 FileHelpers 比使用 CSVHelper 更复杂,您可以在其中以简单的方式创建映射。如果您使用 CsvDataReader,那么您可以使用ClassMap在列标题和属性之间移动,甚至为您实际想要的列指定特定索引。
void Main()
{
var config = new CsvConfiguration(CultureInfo.InvariantCulture)
{
HasHeaderRecord = false,
};
using (var reader = new StreamReader("path\\to\\file.csv"))
using (var csv = new CsvReader(reader, config))
{
csv.Context.RegisterClassMap<FooMap>();
csv.Context.RegisterClassMap<BarMap>();
var fooRecords = new List<Foo>();
var barRecords = new List<Bar>();
while (csv.Read())
{
switch (csv.GetField(0))
{
case "A":
fooRecords.Add(csv.GetRecord<Foo>());
break;
case "B":
barRecords.Add(csv.GetRecord<Bar>());
break;
default:
throw new InvalidOperationException("Unknown record type.");
}
}
}
}
public class Foo
{
public int Id { get; set; }
public string Name { get; set; }
}
public class Bar
{
public Guid Id { get; set; }
public string Name { get; set; }
}
public sealed class FooMap : ClassMap<Foo>
{
public FooMap()
{
Map(m => m.Id).Index(1);
Map(m => m.Name).Index(2);
}
}
public sealed class BarMap : ClassMap<Bar>
{
public BarMap()
{
Map(m => m.Id).Index(1);
Map(m => m.Name).Index(2);
}
}
推荐阅读
- ansible - junos_l2_interface 删除描述,不是吗?
- javascript - 渲染对象 React 数组
- android-toolbar - 在 androidx.appcompat.app.ActionBarDrawerToggle 中不显示汉堡包按钮
- typescript - 具有接口类型之一的变量?
- qt - 由于 ssl 问题,无法在 Ubuntu 上安装 QT4
- reactjs - 动态组件在 React 中不起作用
- javascript - 为什么传递函数 ref 而不是调用函数的 lambda 会有所不同?
- c# - 过滤同一 ObservableCollection 的多个 CollectionView - WPF
- java - 按对象中的不同参数对 ArrayList 进行排序
- c++ - Performance vs Readability: Local copies in functions