将包含多个 json 对象的字符串解析为更方便的内容
Parse a string containing several json objects into something more convenient
这里问题的症结在于我不懂任何 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");
}
}
我大致在滚动足够的解析器来计算大括号来计算在哪里拆分字符串,但我希望库支持会为我做这件事。
理想的最终结果是您选择的顺序数据结构(列表、向量?不关心)包含一个 System.Xml.Linq.XElement
用于每个嵌入字符串中的 json 对象。
谢谢!
编辑:大致可行的示例,主要归功于 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");
}
}
您将要使用 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);
}
}
}
}
这里问题的症结在于我不懂任何 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");
}
}
我大致在滚动足够的解析器来计算大括号来计算在哪里拆分字符串,但我希望库支持会为我做这件事。
理想的最终结果是您选择的顺序数据结构(列表、向量?不关心)包含一个 System.Xml.Linq.XElement
用于每个嵌入字符串中的 json 对象。
谢谢!
编辑:大致可行的示例,主要归功于 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");
}
}
您将要使用 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);
}
}
}
}