将C#的复杂类型转换为YAML

星际争霸

我是YAML的初学者,正在研究如何将YAML解析为C#。在这里,我试图解析C#对象模块,其中包含复杂对象类型的数据,例如C#中的DataTable类或Ty​​pe类。我知道如何使用YAMLDotNet库转换基本类型,但实际上不知道如何对此类类型执行相同的操作。请帮忙。

安托万·奥布里

ADataTable是一个失去属性的复杂对象。最简单的方法是将与您相关的数据提取到更简单的数据结构中,然后对其进行序列化。但是,IYamlTypeConverter如果您确实愿意,可以创建一个自定义这是一个示例,它将序列化表的列名和类型以及行的值:

public class DataTableTypeConverter : IYamlTypeConverter
{
    public bool Accepts(Type type)
    {
        return typeof(DataTable).IsAssignableFrom(type);
    }

    public object ReadYaml(IParser parser, Type type)
    {
        var table = new DataTable();

        parser.Expect<MappingStart>();

        ReadColumns(parser, table);
        ReadRows(parser, table);

        parser.Expect<MappingEnd>();

        return table;
    }

    private static void ReadColumns(IParser parser, DataTable table)
    {
        var columns = parser.Expect<Scalar>();
        if (columns.Value != "columns")
        {
            throw new YamlException(columns.Start, columns.End,
                                    "Expected a scalar named 'columns'");
        }

        parser.Expect<MappingStart>();
        while (parser.Allow<MappingEnd>() == null)
        {
            var columnName = parser.Expect<Scalar>();
            var typeName = parser.Expect<Scalar>();

            table.Columns.Add(columnName.Value, Type.GetType(typeName.Value));
        }
    }

    private static void ReadRows(IParser parser, DataTable table)
    {
        var columns = parser.Expect<Scalar>();
        if (columns.Value != "rows")
        {
            throw new YamlException(columns.Start, columns.End,
                                    "Expected a scalar named 'rows'");
        }

        parser.Expect<SequenceStart>();
        while (parser.Allow<SequenceEnd>() == null)
        {
            var row = table.NewRow();

            var columnIndex = 0;
            parser.Expect<SequenceStart>();
            while (parser.Allow<SequenceEnd>() == null)
            {
                var value = parser.Expect<Scalar>();
                var columnType = table.Columns[columnIndex].DataType;
                row[columnIndex] = TypeConverter.ChangeType(value.Value, columnType);
                ++columnIndex;
            }

            table.Rows.Add(row);
        }
    }

    public void WriteYaml(IEmitter emitter, object value, Type type)
    {
        var table = (DataTable)value;
        emitter.Emit(new MappingStart());

        EmitColumns(emitter, table);
        EmitRows(emitter, table);

        emitter.Emit(new MappingEnd());
    }

    private static void EmitColumns(IEmitter emitter, DataTable table)
    {
        emitter.Emit(new Scalar("columns"));
        emitter.Emit(new MappingStart(null, null, true, MappingStyle.Block));
        foreach (DataColumn column in table.Columns)
        {
            emitter.Emit(new Scalar(column.ColumnName));
            emitter.Emit(new Scalar(column.DataType.AssemblyQualifiedName));
        }
        emitter.Emit(new MappingEnd());
    }

    private static void EmitRows(IEmitter emitter, DataTable table)
    {
        emitter.Emit(new Scalar("rows"));
        emitter.Emit(new SequenceStart(null, null, true, SequenceStyle.Block));

        foreach (DataRow row in table.Rows)
        {
            emitter.Emit(new SequenceStart(null, null, true, SequenceStyle.Flow));
            foreach (var item in row.ItemArray)
            {
                var value = TypeConverter.ChangeType<string>(item);
                emitter.Emit(new Scalar(value));
            }
            emitter.Emit(new SequenceEnd());
        }

        emitter.Emit(new SequenceEnd());
    }
}

它的用法如下:

var table = new DataTable();
table.Columns.Add("id", typeof(int));
table.Columns.Add("name", typeof(string));
table.Columns.Add("description", typeof(string));

table.Rows.Add(1, "first", "The first row");
table.Rows.Add(2, "second", "The second row");

// Serialize
var serializer = new SerializerBuilder()
    .WithTypeConverter(new DataTableTypeConverter())
    .Build();

var yaml = serializer.Serialize(table);

// Deserialize
var deserializer = new DeserializerBuilder()
    .WithTypeConverter(new DataTableTypeConverter())
    .Build();

var parsedTable = deserializer.Deserialize<DataTable>(yaml);

在此示例中,序列化的YAML是:

columns:
  id: System.Int32, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
  name: System.String, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
  description: System.String, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
rows:
- [1, first, The first row]
- [2, second, The second row]

本文收集自互联网,转载请注明来源。

如有侵权,请联系[email protected] 删除。

编辑于
0

我来说两句

0条评论
登录后参与评论

相关文章

来自分类Dev

将C#soap客户端转换为PHP(转换复杂类型的问题)

来自分类Dev

如何将复杂类型转换为动作结果

来自分类Dev

将List <int>转换为复杂类型的列表

来自分类Dev

如何将复杂类型转换为动作结果

来自分类Dev

LINQ to Entity:如何将复杂类型转换为DTO

来自分类Dev

如何在Pytorch中将张量转换为复杂类型?

来自分类Dev

从C ++到C#:PInvoke \将具有复杂类型的回调封送处理

来自分类Dev

如何将Fortran的复杂类型传递给C#?

来自分类Dev

实体框架将多个列映射到C#复杂类型

来自分类Dev

使用 MSDN Microsoft.Xml.XMLGen( XmlSampleGenerator API) 将复杂类型的 XSD 转换为 XML 时出现问题

来自分类Dev

AutoMapper复杂类型对象映射C#

来自分类Dev

在C#中处理复杂类型的xml-reader

来自分类Dev

将C ++类型转换为C#

来自分类Dev

将JSON转换为C#类型

来自分类Dev

Linq to Entities和复杂类型转换

来自分类Dev

将复杂的json转换为c#类

来自分类Dev

将JSON转换为C#复杂对象

来自分类Dev

将复杂的嵌套 JSON 数组转换为 DataTable - C#

来自分类Dev

将C#类型转换为类型数组的类型

来自分类Dev

将C#类型转换为类型数组的类型

来自分类Dev

将包含复杂类型数组的复杂类型传递到Web API

来自分类Dev

复杂类型字段

来自分类Dev

Ksoap复杂类型

来自分类Dev

如何使用XDocument从c#中的复杂类型xml解析文本?

来自分类Dev

如何在C#中使用复杂类型的REST服务?

来自分类Dev

C#反序列化扩展XML复杂类型

来自分类Dev

具有复杂类型集合的 C# odata 操作失败

来自分类Dev

Mysql EF6 C#中如何根据存储过程生成复杂类型

来自分类Dev

将复杂的条件从 C 转换为 Fortran

Related 相关文章

热门标签

归档