2017-08-28 2 views
0

In JSON.Net kann ich eine JSON-Datei in eine Datenstruktur lesen und dann nur die Eigenschaften, die ich interessiere, in Objekte konvertieren. Zum Beispiel, wenn ich eine JSON-Datei wieGibt es eine Möglichkeit, eine bestimmte Eigenschaft eines YAML-Dokuments zu deserialisieren?

{ 
    "Bob": { 
       "Steve": 5 
      } 
} 

haben kann ich das Objekt erhalten, wie so:

class SteveObject { 
    public int Steve; 
} 

var jsonSerializer = JsonSerializer.Create() 
var jsonFile = JObject.Parse(text); 
vat steveObject = jsonFile["Bob"].ToObject<SteveObject>(jsonSerializer) 

Wie mache ich das Gleiche mit YAMLDotNet oder SharpYaml? I.e. wenn ich eine YAML-Datei wie

Bob: 
    Steve: 5 

Wie haben Sie rekonstruieren ich die SteveObject aus, dass ohne das äußere Objekt erstellen zu müssen?

Antwort

0

Ok, ich habe einen Code mit SharpYaml geschrieben, der eine vereinfachte JPath-Abfrage benötigt und das angeforderte Objekt zurückgibt.

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(); 
    } 

die oben YAML folgende Arbeiten Gegeben:

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 

Sicher wünschen es eine Bibliothek dafür waren, though.

Verwandte Themen