3

Hi so am trying to parse this JSON line but i got some others that are like this in files thats why i want to automate this so i can remove the invalid lines to make the file a valid JSON for reading, The problem is that the JSON contains multiple JSON in 1 line

Example:

{"item":"value"}{"anotheritem":"value"}

Is there anyway to remove

{"anotheritem":"value"}

So it turns in to a valid JSON that is readable to start parsing the files

I tried doing using StreamReader cause there in a file i have multiple files that contain these invalid JSON

So i got it to be able to detect the Invalid JSON but for some reason i can't get it to read the JSON so i can use .remove to remove the invalid line

using (StreamReader r = new StreamReader(itemDir))
{
    string json = r.ReadToEnd();
    if (json.Contains("anotheritem"))
    {
        JObject NoGood = JObject.FromObject(json);
        MessageBox.Show(NoGood.ToString());
    }
}

The Error:

Object serialized to String. JObject instance expected.

Thank you all for your time and help.

6
  • Your json seems to be just one big line, could you narrow down what is problematic with it? Commented Jul 29, 2016 at 8:42
  • @LasseV.Karlsen There are two distinct objects, without an array-wrapper or separator. Commented Jul 29, 2016 at 8:44
  • Made it smaller than it was by removing the items data it will now show the problem more clear thanks. Commented Jul 29, 2016 at 8:44
  • Then it isn't JSON, you should complain to whoever made the "json" content in the first place. Commented Jul 29, 2016 at 8:45
  • Ah ye good idea edited the question. Commented Jul 29, 2016 at 8:46

2 Answers 2

7

If each object are side by side without space or any other character, you can convert your string to an json array.

string value = "{\"item\":\"value\"}{\"anotheritem\":\"value\"}";
string arrayValue = "[" + value.Replace("}{", "},{") + "]";
var array = JArray.Parse(arrayValue);
var goopArray = array.OfType<JObject>().Where(o => o.Property("anotheritem") == null);

⚠️ Edit : see my second answer. More robust solution. More modern. And support dotnet core builtin json serializer.

Sign up to request clarification or add additional context in comments.

1 Comment

Awesome idea but var array = JArray.Parse(value); is var array = JArray.Parse(arrrayValue); Thank you :)
1

Json.Net

Even better solution, Json.NET have a builtin feature for this exact scenario. See Read Multiple Fragments With JsonReader

The JsonTextReader have a property SupportMultipleContent that allow to read consecutive items when set to true

string value = "{\"item\":\"value\"}{\"anotheritem\":\"value\"}";

var reader = new JsonTextReader(new System.IO.StringReader(value));
reader.SupportMultipleContent = true;

var list = new List<JObject>();
while (reader.Read())
{
    var item = JObject.Load(reader);
    list.Add(item);
}

System.Text.Json

If you want to use System.Text.Json, it's also acheivable. They are no SupportMultipleContent property but Utf8JsonReader will do the job for you.

string value = "{\"item\":\"value\"}{\"anotheritem\":\"value\"}";

var bytes = Encoding.UTF8.GetBytes(value).AsSpan();

var list = new List<JsonDocument>();
while (bytes.Length != 0)
{
    var reader = new Utf8JsonReader(bytes);

    var item = JsonDocument.ParseValue(ref reader);
    list.Add(item);
    
    bytes = bytes.Slice((int) reader.BytesConsumed);
}

System.Text.Json Net 9

Dotnet 9 add an option to read multiple json documents. See here for the announcement. Set JsonReaderOptions.AllowMultipleValues to true will allow you to use a single instance of Utf8JsonReader and remove manual span slicing.

ReadOnlySpan<byte> value = """{"item":"value"}{"anotheritem":"value"}"""u8;

JsonReaderOptions options = new()
{
    AllowMultipleValues = true
};

var list = new List<JsonDocument>();

var reader = new Utf8JsonReader(value, options);
while (reader.Read())
{
    list.Add(JsonDocument.ParseValue(ref reader));
}

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.