简体   繁体   English

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

[英]Parse a string containing several json objects into something more convenient

The crux of the problem here is that I don't know any C#, yet find myself adding a feature to some test infrastructure which happens to be written in C#. 问题的症结在于,我不了解任何C#,但发现自己在一些恰好用C#编写的测试基础架构中添加了功能。 I suspect this question is entirely trivial and beg your patience in answering. 我怀疑这个问题完全无关紧要,请您耐心等待。 My colleagues who originally wrote this stuff are all out of the office. 最初写这些东西的同事都不在办公室。

I am parsing a string representing one or more json objects. 我正在解析表示一个或多个json对象的字符串。 So far I can get the first object, but can't work out how to access the remainder. 到目前为止,我可以获取第一个对象,但是无法计算出如何访问其余对象。

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

I'm roughly at the point of rolling enough of a parser to work out where to split the string by counting braces but am hoping that the library support will do this for me. 我大概是在滚动足够多的解析器,以计算括号的位置来拆分字符串,但我希望库支持为我做这件事。

The ideal end result is a sequential datastructure of your choice (list, vector? don't care) containing one System.Xml.Linq.XElement for each json object embedded in the string. 理想的最终结果是您选择的顺序数据结构(列表,向量?不在乎),对于嵌入在字符串中的每个json对象都包含一个System.Xml.Linq.XElement

Thanks! 谢谢!

edit: Roughly viable example, mostly due to George Richardson - I'm playing fast and loose with the type system (not sure dynamic is available in C#3.0), but the end result seems to be predictable. 编辑:大致可行的示例,主要是由于乔治·理查德森(George Richardson)-我正在使用类型系统(在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");
    }
}

You are going to want to use JSON.net for your actual deserialization needs. 您将要使用JSON.net满足实际的反序列化需求。 The big problem I see here is that your json data is just being concatenated together which means you are going to have to extract each object from the string. 我在这里看到的最大问题是您的json数据只是串联在一起,这意味着您将不得不从字符串中提取每个对象。 Luckily json.net's JsonReader has a SupportMultipleContent property which does just this 幸运的是,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);
            }
        }
    }
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM