2016-11-25 103 views
1

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

回答

0

A DataTable是一个失去了属性的复杂对象。最简单的方法是将与您相关的数据提取到更简单的数据结构中,然后序列化。但是,如果您真的想要创建自定义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] 
+0

谢谢:)它工作(y) – Anonymous