将包含多个 json 对象的字符串解析为更方便的对象

本文关键字:对象 方便 字符串 json 包含多 | 更新日期: 2023-09-27 17:56:54

这里问题的症结在于我不懂任何C#,但发现自己向某些测试基础设施添加了一个功能,而这个功能恰好是用C#编写的。我怀疑这个问题完全是微不足道的,请您耐心回答。我最初写这些东西的同事都不在办公室。

我正在解析表示一个或多个 json 对象的字符串。到目前为止,我可以得到第一个对象,但无法弄清楚如何访问其余对象。

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

大致处于滚动足够多的解析器以通过计算大括号来确定在哪里拆分字符串的地步,但我希望库支持能为我做到这一点。

理想的最终结果是您选择的顺序数据结构(列表,向量?不在乎),其中包含字符串中嵌入的每个json对象的一个System.Xml.Linq.XElement

谢谢!

编辑:大致可行的示例,主要是由于乔治理查森 - 我正在快速而松散地使用类型系统(不确定动态在 C#3.0 中是否可用),但最终结果似乎是可预测的。

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

将包含多个 json 对象的字符串解析为更方便的对象

您将希望使用 JSON.net 来满足实际的反序列化需求。我在这里看到的最大问题是您的 json 数据只是连接在一起,这意味着您将不得不从字符串中提取每个对象。幸运的是,json.net的JsonReader有一个SupportMultipleContent属性,可以做到这一点。

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