我正在尝试根据我在 yaml 文件的输出中获得的值来格式化对象的属性名称。我正在使用 yamldotnet 库。下面是我的课
State.cs
public class State
{
public string name { get; set; }
public List<Operation> operations { get; set; }
}
Operation.cs
public class Operation
{
public string name { get; set; }
public string type { get; set; }
}
在状态类中,我有操作列表。序列化后,我得到以下 yaml 输出:
states:
- name: uPError
operations:
- name: switch on uP
type: entry
- name: switch off uP
type: exit
- name: test Do
type: do
但我打算显示的格式如下:
states:
- name: uPError
entryActions: [switch on uP]
exitActions: [switch off uP]
doActions: [test Do]
我正在获取类型及其名称,根据类型,我需要将其更改为 entryAction、exitActions 或 doActions 和然后附加相应的名称。我怎样才能实现上述预期格式?提前致谢。
答案 0 :(得分:0)
实现此目的的一种方法是实现 IYamlTypeConverter
以自定义 State
类型的转换。这使您可以控制类的整个序列化:
public class StateConverter : IYamlTypeConverter
{
public bool Accepts(Type type)
{
return type == typeof(State);
}
public object? ReadYaml(IParser parser, Type type)
{
var state = new State { operations = new List<UserQuery.Operation>() };
parser.Consume<MappingStart>();
while (!parser.TryConsume<MappingEnd>(out var _))
{
var key = parser.Consume<Scalar>().Value;
if (key == nameof(state.name))
{
state.name = parser.Consume<Scalar>().Value;
}
else
{
parser.Consume<SequenceStart>();
while (!parser.TryConsume<SequenceEnd>(out var _))
{
state.operations.Add(new Operation
{
type = key,
name = parser.Consume<Scalar>().Value,
});
}
}
}
return state;
}
public void WriteYaml(IEmitter emitter, object? value, Type type)
{
var state = (State)value!;
emitter.Emit(new MappingStart());
emitter.Emit(new Scalar(nameof(state.name)));
emitter.Emit(new Scalar(state.name));
foreach (var operationGroup in state.operations.GroupBy(o => o.type))
{
emitter.Emit(new Scalar(operationGroup.Key));
emitter.Emit(new SequenceStart(null, null, false, SequenceStyle.Flow));
foreach (var operation in operationGroup)
{
emitter.Emit(new Scalar(operation.name));
}
emitter.Emit(new SequenceEnd());
}
emitter.Emit(new MappingEnd());
}
}
您需要在 SerializerBuilder
和 DeserializerBuilder
上注册该类型:
var serializer = new SerializerBuilder()
.WithTypeConverter(new StateConverter())
.Build();
var deserializer = new DeserializerBuilder()
.WithTypeConverter(new StateConverter())
.Build();