gpt4 book ai didi

c# - 反序列化 YAML "Table"数据

转载 作者:太空狗 更新时间:2023-10-29 23:38:10 27 4
gpt4 key购买 nike

我正在使用 yamldotnet 和 c# 反序列化由第三方软件应用程序创建的文件。以下 YAML 文件示例均适用于应用程序:

#File1
Groups:
- Name: ATeam
FirstName, LastName, Age, Height:
- [Joe, Soap, 21, 184]
- [Mary, Ryan, 20, 169]
- [Alex, Dole, 24, 174]

#File2
Groups:
- Name: ATeam
FirstName, LastName, Height:
- [Joe, Soap, 184]
- [Mary, Ryan, 169]
- [Alex, Dole, 174]

请注意,File2 没有任何 Age 列,但反序列化器仍必须识别每行的第三个值是高度而不是年龄。该数据应该代表一张人表。以 File1 为例,Mary Ryan 20 岁,高度 169 厘米。反序列化器需要了解它拥有的列(对于 File2,它只有 FirstName、LastName 和 Height)并将数据相应地存储在正确的对象中:Mary Ryan 高度 169 厘米。

同样,程序文档指出列的顺序并不重要,因此下面的 File3 是表示 File2 中数据的同样有效的方式,即使现在高度在第一位也是如此:

#File3
Groups:
- Name: ATeam
Height, FirstName, LastName:
- [184, Joe, Soap]
- [169, Mary, Ryan]
- [174, Alex, Dole]

我有几个问题:

  1. 这是标准的 YAML 吗? - 我找不到任何关于使用的信息同一行上的一些键,后跟一个冒号和列表表示数据表的值。
  2. 我如何使用 yamldotnet 反序列化它?在那里我可以做些什么来帮助它?
  3. 如果我不能使用 yamldotnet,我该怎么办?

最佳答案

正如其他答案所述,这是有效的 YAML。但是,文档的结构是特定于应用程序的,并没有使用 YAML 的任何特殊功能来表达表格。

您可以使用 YamlDotNet 轻松解析此文档。但是你会遇到两个困难。首先是,由于列名放在键内,您需要使用一些自定义序列化代码来处理它们。第二个是您需要实现某种抽象,以便能够以表格方式访问数据。

我已经提出了一个概念证明,将说明如何解析和读取数据。

首先,创建一个类型来保存来自 YAML 文档的信息:

public class Document
{
public List<Group> Groups { get; set; }
}

public class Group
{
public string Name { get; set; }

public IEnumerable<string> ColumnNames { get; set; }

public IList<IList<object>> Rows { get; set; }
}

然后实现IYamlTypeConverter来解析Group类型:

public class GroupYamlConverter : IYamlTypeConverter
{
private readonly Deserializer deserializer;

public GroupYamlConverter(Deserializer deserializer)
{
this.deserializer = deserializer;
}

public bool Accepts(Type type)
{
return type == typeof(Group);
}

public object ReadYaml(IParser parser, Type type)
{
var group = new Group();

var reader = new EventReader(parser);
do
{
var key = reader.Expect<Scalar>();
if(key.Value == "Name")
{
group.Name = reader.Expect<Scalar>().Value;
}
else
{
group.ColumnNames = key.Value
.Split(',')
.Select(n => n.Trim())
.ToArray();

group.Rows = deserializer.Deserialize<IList<IList<object>>>(reader);
}
} while(!reader.Accept<MappingEnd>());
reader.Expect<MappingEnd>();

return group;
}

public void WriteYaml(IEmitter emitter, object value, Type type)
{
throw new NotImplementedException("TODO");
}
}

最后,将转换器注册到反序列化器中,反序列化文档:

var deserializer = new Deserializer();
deserializer.RegisterTypeConverter(new GroupYamlConverter(deserializer));

var document = deserializer.Deserialize<Document>(new StringReader(yaml));

You can test the fully working example here

这只是一个概念证明,但它应该作为您自己实现的指南。可以改进的地方包括:

  • 检查和处理无效文件。
  • 改进 Group 类。也许让它不可变,并添加一个索引器。
  • 如果需要序列化支持,则实现 WriteYaml 方法。

关于c# - 反序列化 YAML "Table"数据,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30894438/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com