在JSON.Net中,我可以将JSON文件读入数据结构,然后只将我感兴趣的属性转换为对象。例如,如果我有一个像
这样的JSON文件{
"Bob": {
"Steve": 5
}
}
我可以像这样得到这个对象:
class SteveObject {
public int Steve;
}
var jsonSerializer = JsonSerializer.Create()
var jsonFile = JObject.Parse(text);
vat steveObject = jsonFile["Bob"].ToObject<SteveObject>(jsonSerializer)
如何使用YAMLDotNet或SharpYaml执行相同的操作?即如果我有像
这样的YAML文件Bob:
Steve: 5
如何从中重构SteveObject
而无需创建外部对象?
答案 0 :(得分:0)
好的,我使用SharpYaml编写了一些代码,它采用简化的JPath查询并返回请求的对象。
public static T ReadPath<T>(Serializer serializer, string yaml, string path) {
var eventReader = new EventReader(new Parser(new StringReader(yaml)));
var streamReader = new MemoryStream(Encoding.UTF8.GetBytes(path ?? ""));
if ((char)streamReader.ReadByte() != '$')
throw new Exception();
if (streamReader.Position == streamReader.Length)
return serializer.Deserialize<T>(eventReader);
eventReader.Expect<StreamStart>();
eventReader.Expect<DocumentStart>();
while (streamReader.Position < streamReader.Length) {
if ((char)streamReader.ReadByte() != '.')
throw new Exception();
eventReader.Expect<MappingStart>();
var currentDepth = eventReader.CurrentDepth;
var nextKey = ReadPropertyName(streamReader);
if (string.IsNullOrEmpty(nextKey))
throw new Exception();
while (eventReader.Peek<Scalar>() == null || eventReader.Peek<Scalar>().Value != nextKey) {
eventReader.Skip();
// We've left the current mapping without finding the key.
if (eventReader.CurrentDepth < currentDepth)
throw new Exception();
}
eventReader.Expect<Scalar>();
}
return serializer.Deserialize<T>(eventReader);
}
public static string ReadPropertyName(MemoryStream stream) {
var sb = new StringBuilder();
while (stream.Position < stream.Length) {
var nextChar = (char) stream.ReadByte();
if (nextChar == '.') {
stream.Position--;
return sb.ToString();
}
sb.Append(nextChar);
}
return sb.ToString();
}
鉴于上述YAML,以下工作如下:
var t = "Bob:\r\n Point: [1.0, 2.0, 3.0]\r\n Steve: 5\r\n";
var serializer = new Serializer(settings);
var s = ReadPath<SteveObject>(serializer, t, "$.Bob"); // { "Steve": 5 }
var s2 = ReadPath<int>(serializer, t, "$.Bob.Steve"); // 5
当然希望有一个这样的图书馆。