2016-07-14 2 views
1

Der Kern des Problems hier ist, dass ich keine C# kenne, aber ich finde, dass ich ein Feature zu einer Testinfrastruktur hinzufüge, die in C# geschrieben wird. Ich vermute, dass diese Frage völlig trivial ist und bitten Sie um Geduld. Meine Kollegen, die dieses Zeug ursprünglich geschrieben haben, sind alle nicht im Büro.Analysieren Sie eine Zeichenfolge, die mehrere JSON-Objekte enthält, in etwas komfortableres

Ich analysiere eine Zeichenfolge, die ein oder mehrere JSON-Objekte darstellt. Bisher kann ich das erste Objekt bekommen, kann aber nicht herausfinden, wie ich auf den Rest zugreifen soll.

public class demo 
{ 
public void minimal() 
{ 
    // Note - the input is not quite json! I.e. I don't have 
    // [{"Name" : "foo"}, {"Name" : "bar"}] 
    // Each individual object is well formed, they just aren't in 
    // a convenient array for easy parsing. 
    // Each string representation of an object are literally concatenated. 

    string data = @"{""Name"": ""foo""} {""Name"" : ""bar""}"; 

    System.Xml.XmlDictionaryReader jsonReader = 
     JsonReaderWriterFactory.CreateJsonReader(Encoding.UTF8.GetBytes(data), 
     new System.Xml.XmlDictionaryReaderQuotas()); 

    System.Xml.Linq.XElement root = XElement.Load(jsonReader); 
    Assert.AreEqual(root.XPathSelectElement("//Name").Value, "foo"); 

    // The following clearly doesn't work 
    Assert.AreEqual(root.XPathSelectElement("//Name").Value, "bar"); 
} 
} 

Ich bin ungefähr an der Stelle des genug eines Parsers Ausrollen zu arbeiten, wo die Zeichenfolge geteilt durch Klammern zu zählen, aber ich hoffe, dass die Bibliothek Unterstützung für mich tun.

Das ideale Endergebnis ist eine sequentielle Datenstruktur Ihrer Wahl (Liste, Vektor? Egal), die ein System.Xml.Linq.XElement für jedes in die Zeichenfolge eingebettete JSON-Objekt enthält.

Danke!

edit: Grob brauchbares Beispiel, hauptsächlich wegen George Richardson - Ich spiele schnell und locker mit dem Typsystem (nicht sicher, dass Dynamik in C# 3.0 verfügbar ist), aber das Endergebnis scheint vorhersehbar zu sein.

public class demo 
{ 
    private IEnumerable<Newtonsoft.Json.Linq.JObject> 
      DeserializeObjects(string input) 
    { 
     var serializer = new JsonSerializer(); 
     using (var strreader = new StringReader(input)) 
     { 
      using (var jsonreader = new JsonTextReader(strreader)) 
      { 
       jsonreader.SupportMultipleContent = true; 
       while (jsonreader.Read()) 
       { 
        yield return (Newtonsoft.Json.Linq.JObject) 
            serializer.Deserialize(jsonreader); 
       } 
      } 
     } 
    } 

    public void example() 
    { 
     string json = @"{""Name"": ""foo""} {""Name"" : ""bar""} {""Name"" : ""baz""}"; 
     var objects = DeserializeObjects(json); 

     var array = objects.ToArray(); 
     Assert.AreEqual(3, array.Length); 
     Assert.AreEqual(array[0]["Name"].ToString(), "foo"); 
     Assert.AreEqual(array[1]["Name"].ToString(), "bar"); 
     Assert.AreEqual(array[2]["Name"].ToString(), "baz"); 
    } 
} 
+1

Verwenden [json.net] (http://www.newtonsoft.com/json). Sind Ihre Daten korrekt? Sollte es sein: '" {Name "": "foo" "}, {" "Name" ":" "bar" "}}" '? – DGibbs

+0

"Korrigieren" könnte es übertreiben. Ich habe kein Array von Objekten zu parsen, ich habe N Objekte buchstäblich miteinander verkettet –

+1

Das Problem ist, dass Sie einen XML-Parser verwenden, um JSON-Daten zu lesen. Verwenden Sie stattdessen einen JSON-Parser. –

Antwort

2

Sie werden JSON.net für Ihre tatsächlichen Deserialisierung Bedürfnisse verwenden wollen. Das große Problem, das ich hier sehe, ist, dass Ihre json Daten nur zusammen verkettet werden, was bedeutet, dass Sie jedes Objekt aus der Zeichenkette extrahieren müssen. Zum Glück json.net die JsonReader hat eine SupportMultipleContent Eigenschaft, die genau dies tut

public void Main() 
{ 
    string json = @"{""Name"": ""foo""} {""Name"" : ""bar""} {""Name"" : ""baz""}"; 
    IEnumerable<dynamic> deserialized = DeserializeObjects(json); 
    string name = deserialized.First().Name; //name is "foo" 
} 

IEnumerable<object> DeserializeObjects(string input) 
{ 
    JsonSerializer serializer = new JsonSerializer(); 
    using (var strreader = new StringReader(input)) { 
     using (var jsonreader = new JsonTextReader(strreader)) { 
      jsonreader.SupportMultipleContent = true; 
      while (jsonreader.Read()) { 
       yield return serializer.Deserialize(jsonreader); 
      } 
     } 
    } 
} 
+0

Sie müssen es nicht hacken, json reader unterstützt die Stütze SupportMultipleContent, die genau für diese Situation verwendet wird. –

+0

@Paul Wow ja das ist großartig. http://stackoverflow.com/questions/26601594/what-is-the-correct-way-to-use-json-net-to-parse-stream-of-json-objects hat alles, was wir hier brauchen. Ich werde meine Antwort aktualisieren –

+0

Verknüpfte Frage ist großartig! Es wird wahrscheinlich ein Duplikat sein, sobald ich herausfinden kann, was der Code eigentlich bedeutet."Stream of json objects" ist eine gute Beschreibung zu –

Verwandte Themen