从 YamlStream 发出序列化类型标签

Issue Serializing Type Tags from YamlStream

我在为 class 创建配置文件时遇到问题,其中包含在我使用 YamlStream API.

时实现相同接口的对象列表

我想保留我放在列表项上的本地标签,以便它们可以从另一个上下文正确反序列化。在我的实际项目中,我必须对 YamlNodes 进行一些预处理。但是,当我想将 YamlDocument 序列化为文件时,本地类型标签丢失了。我看到标签在转换为 YamlStream 时被解析(某些节点已正确设置标签 属性)。但是,经过处理后,它们被序列化,没有标签。

我有一些我在这个 repo 中尝试过的例子:https://github.com/mariotee/YamlDotNetIssue

var stream = new YamlStream();
stream.Load(new StringReader(yaml));

//pre processing would go here

using (var wr = new StringWriter())
{
    stream.Save(wr, false);
    File.WriteAllText("path", wr.ToString());
}

预期结果:

pets:  
- !Cat
  name: skippy
  likesMilk: true
- !Cat
  name: felix
  likesMilk: true
- !Dog
  name: ralf
  likesBones: true
- !Hamster
  name: Hamtaro
  likesTv: true
...

实际结果:

pets:
- name: skippy
  likesMilk: true
- name: felix
  likesMilk: true
- name: ralf
  likesBones: true
- name: Hamtaro
  likesTv: true
...

正如我评论的那样,这是一个错误。但是,您可以通过提供自己的 IEmitter 实现并将 MappingStart 的 IsImplicit 属性 强制为 false:

来解决此问题
public static void Main()
{
    var yaml = @"
pets:  
- !Cat
  name: skippy
  likesMilk: true
- !Cat
  name: felix
  likesMilk: true
- !Dog
  name: ralf
  likesBones: true
- !Hamster
  name: Hamtaro
  likesTv: true
...
";

    var stream = new YamlStream();
    stream.Load(new StringReader(yaml));
    stream.Save(new MappingFix(new Emitter(Console.Out)), false);
}

public class MappingFix : IEmitter
{
    private readonly IEmitter next;

    public MappingFix(IEmitter next)
    {
        this.next = next;
    }

    public void Emit(ParsingEvent @event)
    {
        var mapping = @event as MappingStart;
        if (mapping != null) {
            @event = new MappingStart(mapping.Anchor, mapping.Tag, false, mapping.Style, mapping.Start, mapping.End);
        }
        next.Emit(@event);
    }
}

这会产生预期的输出:

pets:
- !Cat
  name: skippy
  likesMilk: true
- !Cat
  name: felix
  likesMilk: true
- !Dog
  name: ralf
  likesBones: true
- !Hamster
  name: Hamtaro
  likesTv: true
...

请注意,这需要最新版本 - YamlDotNet 6.1.1