Resolved How to get values from elements in JSON without indexing?

WeyardWiz

Member
Joined
Oct 23, 2020
Messages
23
Programming Experience
3-5
I have the following code that extracts json elements values and outputs to csv:

C#:
public static void Json_to_Csv(string jsonInputFile, string csvFile)
{
    using (var p = new ChoJSONReader(jsonInputFile).WithJSONPath("$..readResults")) // "readResults": [
    {
        using (var w = new ChoCSVWriter(csvFile).WithFirstLineHeader())
        {
            w.Write(p
                .Select(r1 =>
                {
                    var lines = (dynamic[])r1.lines;
                    return new
                    {
                        FileName = jsonInputFile,
                        Page = r1.page,
                        PracticeName = lines[2].text,
                        OwnerFullName = lines[4].text,
                        OwnerEmail = lines[6].text,
                    };
                }
        }
    }
}

csv output:

File Name,Page,Practice Name,Owner Full Name,Owner Email
file1.json,1,Some Practice Name,Bob Lee,Bob@someemail.com

Currently there is no other contextual information on each item to reference them so the only way is by indexing, e.g. lines[2]

This works for now but I may have other JSON files that have an extra field, therefore the values pulled will be wrong.

In order to address this scenario, how can i pull the values contextually instead of indexing the lines?

Ive tried
C#:
PracticeName = lines["Practice Name"].text

but i get Cannot implicitly convert type string to int error


file1.json sample:

JSON:
{
  "status": "succeeded",
  "createdDateTime": "2020-10-22T19:35:35Z",
  "lastUpdatedDateTime": "2020-10-22T19:35:36Z",
  "analyzeResult": {
    "version": "3.0.0",
    "readResults": [
      {
        "page": 1,
        "angle": 0,
        "width": 8.5,
        "height": 11,
        "unit": "inch",
        "lines": [        
          {
            "boundingBox": [
              0.5016,
              1.9141,
              2.5726,
              1.9141,
              2.5726,
              2.0741,
              0.5016,
              2.0741
            ],          
           "text": "Account Information",
            "words": [
              {
                "boundingBox": [
                  0.5016,
                  1.9345,
                  1.3399,
                  1.9345,
                  1.3399,
                  2.0741,
                  0.5016,
                  2.0741
                ],
                "text": "Account",
                "confidence": 1
              },
              {
                "boundingBox": [
                  1.3974,
                  1.9141,
                  2.5726,
                  1.9141,
                  2.5726,
                  2.0741,
                  1.3974,
                  2.0741
                ],
                "text": "Information",
                "confidence": 1
              }
            ]
          },
          {
            "boundingBox": [
              1.7716,
              2.4855,
              2.8793,
              2.4855,
              2.8793,
              2.6051,
              1.7716,
              2.6051
            ],
            "text": "Practice Name",
            "words": [
              {
                "boundingBox": [
                  1.7716,
                  2.4855,
                  2.3803,
                  2.4855,
                  2.3803,
                  2.6051,
                  1.7716,
                  2.6051
                ],
                "text": "Practice",
                "confidence": 1
              },
              {
                "boundingBox": [
                  2.4362,
                  2.4948,
                  2.8793,
                  2.4948,
                  2.8793,
                  2.6051,
                  2.4362,
                  2.6051
                ],
                "text": "Name",
                "confidence": 1
              }
            ]
          },
          {
            "boundingBox": [
              2.9993,
              2.5257,
              4.7148,
              2.5257,
              4.7148,
              2.714,
              2.9993,
              2.714
            ],
            "text": "Some Practice Name",
            "words": [
              {
                "boundingBox": [
                  3.0072,
                  2.5385,
                  3.6546,
                  2.5284,
                  3.6516,
                  2.7131,
                  3.0105,
                  2.712
                ],
                "text": "Some",
                "confidence": 0.984
              },
              {
                "boundingBox": [
                  3.6887,
                  2.5281,
                  4.2112,
                  2.5262,
                  4.2028,
                  2.7159,
                  3.6854,
                  2.7132
                ],
                "text": "Parctice",
                "confidence": 0.986
              },
              {
                "boundingBox": [
                  4.2453,
                  2.5263,
                  4.7223,
                  2.5297,
                  4.7091,
                  2.72,
                  4.2366,
                  2.7161
                ],
                "text": "Name",
                "confidence": 0.986
              }
            ]
          },
          {
            "boundingBox": [
              1.6116,
              2.9999,
              2.8816,
              2.9999,
              2.8816,
              3.1158,
              1.6116,
              3.1158
            ],
            "text": "Owner Full Name",
            "words": [
              {
                "boundingBox": [
                  1.6116,
                  3.0039,
                  2.1026,
                  3.0039,
                  2.1026,
                  3.1157,
                  1.6116,
                  3.1157
                ],
                "text": "Owner",
                "confidence": 1
              },
              {
                "boundingBox": [
                  2.1541,
                  2.9999,
                  2.3784,
                  2.9999,
                  2.3784,
                  3.1158,
                  2.1541,
                  3.1158
                ],
                "text": "Full",
                "confidence": 1
              },
              {
                "boundingBox": [
                  2.4384,
                  3.0052,
                  2.8816,
                  3.0052,
                  2.8816,
                  3.1155,
                  2.4384,
                  3.1155
                ],
                "text": "Name",
                "confidence": 1
              }
            ]
          },
          {
            "boundingBox": [
              2.9993,
              3.0242,
              3.6966,
              3.0242,
              3.6966,
              3.2125,
              2.9993,
              3.2014
            ],
            "text": "Bob Lee",
            "words": [
              {
                "boundingBox": [
                  3.0063,
                  3.0303,
                  3.3439,
                  3.0349,
                  3.3461,
                  3.2125,
                  3.007,
                  3.2081
                ],
                "text": "Bob",
                "confidence": 0.987
              },
              {
                "boundingBox": [
                  3.3788,
                  3.0349,
                  3.6931,
                  3.0326,
                  3.697,
                  3.2121,
                  3.3813,
                  3.2125
                ],
                "text": "Lee",
                "confidence": 0.983
              }
            ]
          },
          {
            "boundingBox": [
              1.945,
              3.5063,
              2.8748,
              3.5063,
              2.8748,
              3.6261,
              1.945,
              3.6261
            ],
            "text": "Owner Email",
            "words": [
              {
                "boundingBox": [
                  1.945,
                  3.5143,
                  2.4359,
                  3.5143,
                  2.4359,
                  3.6261,
                  1.945,
                  3.6261
                ],
                "text": "Owner",
                "confidence": 1
              },
              {
                "boundingBox": [
                  2.4874,
                  3.5063,
                  2.8748,
                  3.5063,
                  2.8748,
                  3.6259,
                  2.4874,
                  3.6259
                ],
                "text": "Email",
                "confidence": 1
              }
            ]
          },
          {
            "boundingBox": [
              3.0104,
              3.5005,
              4.6042,
              3.5005,
              4.6042,
              3.6888,
              3.0104,
              3.6777
            ],
            "text": "bob@gmail.com",
            "words": [
              {
                "boundingBox": [
                  3.0212,
                  3.5047,
                  4.5837,
                  3.5039,
                  4.5769,
                  3.6886,
                  3.0129,
                  3.6787
                ],
                "text": "bob@gmail.com",
                "confidence": 0.951
              }
            ]
          }
        ]
      }
    ]
  }
}
 
Last edited by a moderator:
Solution
The following outputs the pairs to the console:
C#:
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using Newtonsoft.Json;

class RootObject
{
    [JsonProperty("analyzeResult")]
    public AnalyzeResult AnalyzeResult { get; set; }
}

class AnalyzeResult
{
    [JsonProperty("readResults")]
    public ReadResults[] ReadResults { get; set; }
}

class ReadResults
{
    [JsonProperty("lines")]
    public Line[] Lines { get; set; }
}

class Line
{
    [JsonProperty("text")]
    public string Text { get; set; }

    public override string ToString() => Text;
}

public static class IEnumerableExtensions
{
    public static IEnumerable<KeyValuePair<T, T>> Pairs<T>(this IEnumerable<T> items)
    {...

JohnH

C# Forum Moderator
Staff member
Joined
Apr 23, 2011
Messages
901
Location
Norway
Programming Experience
10+
Put a breakpoint after the groups assignment and inspect it in VS, there you can see all lines that have been grouped and inside each group you can see the strings within the group. Converting to dictionary/lookup just take first string in each group as key and the rest as values.
Group {"A", "B", "C"} becomes key "A" and value {"B", "C"} for dictionary, or value {{"B", "C"}} for lookup.
Groups {"A", "B1", "C1"} and {"A", "B2", "C2"} is not valid for dictionary, and becomes key "A" and value {{"B1", "C1"}, {"B2", "C2"}} for lookup.
 

Sheepings

Retired Programmer
Staff member
Joined
Sep 5, 2018
Messages
1,801
Location
UK
Programming Experience
10+

WeyardWiz

Member
Joined
Oct 23, 2020
Messages
23
Programming Experience
3-5
Put a breakpoint after the groups assignment and inspect it in VS, there you can see all lines that have been grouped and inside each group you can see the strings within the group. Converting to dictionary/lookup just take first string in each group as key and the rest as values.
Group {"A", "B", "C"} becomes key "A" and value {"B", "C"} for dictionary, or value {{"B", "C"}} for lookup.
Groups {"A", "B1", "C1"} and {"A", "B2", "C2"} is not valid for dictionary, and becomes key "A" and value {{"B1", "C1"}, {"B2", "C2"}} for lookup.
This is what im seeing. the lookup is NULL but why?

1605758253042.png

1605758454332.png


System.NullReferenceException
HResult=0x80004003
Message=Object reference not set to an instance of an object.

1605758688332.png

1605758748060.png
 

WeyardWiz

Member
Joined
Oct 23, 2020
Messages
23
Programming Experience
3-5
I said "Put a breakpoint after the groups assignment", not at it. On that line groups has not been assigned yet, and you can see in debugger that groups in null too.
oh i thought with step into operator it continues the execution regardless. Anyhow, i put it after and serverSetup is still NULL...

1605796942507.png

1605797008294.png

1605797192608.png


Interestingly, i see Key is "Server Setup" but no Values like i would with dictionary!
 

JohnH

C# Forum Moderator
Staff member
Joined
Apr 23, 2011
Messages
901
Location
Norway
Programming Experience
10+
I explained this in post 22, and again in post 38, yet you haven't changed the code. Element [0] is the first value (set), and it contains the strings listed in Results View. Reason for this display is that Linq is a query that needs to evaluated as it is iterated, you see that the value of [0] is an iterator. Element [0] can also be accessed with First extension method. If there were a second set for same key that would have been a second element [1] under key that would also have its own Result View of string values associated with it.
 

WeyardWiz

Member
Joined
Oct 23, 2020
Messages
23
Programming Experience
3-5
I explained this in post 22, and again in post 38, yet you haven't changed the code. Element [0] is the first value (set), and it contains the strings listed in Results View. Reason for this display is that Linq is a query that needs to evaluated as it is iterated, you see that the value of [0] is an iterator. Element [0] can also be accessed with First extension method. If there were a second set for same key that would have been a second element [1] under key that would also have its own Result View of string values associated with it.
If i changed the code to the suggested in post 22, i am getting "V"...
C#:
var serverSetup = lookup["Server Setup"].First().First();
i need to somehow retain the condition but that result in sequence contains no elements...
C#:
            var serverSetup = lookup["Server Setup"]
                .SkipWhile(s => s.ToString().ToUpper() != "V").First().First();
 

WeyardWiz

Member
Joined
Oct 23, 2020
Messages
23
Programming Experience
3-5
You need to understand what the code refers to:

lookup["Server Setup"].First():
View attachment 1211

.First();
View attachment 1212
OMG this is how LOL
C#:
            var serverSetup = lookup["Server Setup"]
                .First().SkipWhile(s => s.ToString().ToUpper() != "V").Skip(1).First();
ok this makes sense. so first we get the SET, evaluate the expression, then get the value.
 
Top Bottom