Assistance required with converting Json in Powershell

I am very new to PowerShell in fact I only started learning this week. I have written an application in C# and I am in the process of attempting to convert this to a PowerShell script. One of the main components of my application is being able to Deserialize and call on elements from a Json report.

Here is my Json code:

[
  {
    "description": "",
    "elements": [
      {
        "description": "",
        "id": "",
        "keyword": "Scenario",
        "line": 27,
        "name": "The author, the title and the price of a book can be seen, ExampleSet0, aaa",
        "tags": [
          {
            "name": "WI10",
            "line": 1
          },
          {
            "name": "test1",
            "line": 1
          },
          {
            "name": "automated",
            "line": 1
          },
          {
            "name": "WI9",
            "line": 1
          }
        ],
        "steps": [],
        "type": "scenario"
      },
      {
        "description": "",
        "id": "",
        "keyword": "Scenario",
        "line": 27,
        "name": "The author, the title and the price of a book can be seen, ExampleSet1, aaa",
        "tags": [
          {
            "name": "WI10",
            "line": 1
          },
          {
            "name": "test2",
            "line": 1
          },
          {
            "name": "automated",
            "line": 1
          },
          {
            "name": "WI9",
            "line": 1
          }
        ],
        "steps": [
          {
            "keyword": "Given ",
            "line": 0,
            "match": {
              "location": "GivenTheFollowingBooks"
            },
            "name": "the following books",
            "result": {
              "duration": 1148.4897,
              "error_message": null,
              "status": "Passed"
            }
          },
          {
            "keyword": "When ",
            "line": 0,
            "match": {
              "location": "WhenIOpenTheDetailsOfBook"
            },
            "name": "I open the details of 'Analysis Patterns'",
            "result": {
              "duration": 127.4364,
              "error_message": null,
              "status": "Passed"
            }
          },
          {
            "keyword": "Then ",
            "line": 0,
            "match": {
              "location": "ThenTheBookDetailsShouldShow"
            },
            "name": "the book details should show",
            "result": {
              "duration": 7.7351,
              "error_message": null,
              "status": "Passed"
            }
          }
        ],
        "type": "scenario"
      }
    ],
    "id": "",
    "keyword": "Feature",
    "line": 3,
    "tags": [
      {
        "name": "automated",
        "line": 1
      },
      {
        "name": "WI9",
        "line": 1
      }
    ],
    "name": "Book details",
    "uri": "Features\\Book Details.feature"
  }
]

I am trying to use “ConvertFrom-Json” in PS to convert this file into an accessible array of objects that I can work with. However when I try the following:

$Report = Get-Content Report.json
$json = ConvertFrom-Json -InputObject "$Report"

I get this as output:

description : 
elements    : {@{description=; id=; keyword=Scenario; line=27; name=The author, the title and the price of a book can be seen, ExampleSet0, aaa; tags=System.Object[]; 
              steps=System.Object[]; type=scenario}, @{description=; id=; keyword=Scenario; line=27; name=The author, the title and the price of a book can be seen, 
              ExampleSet1, aaa; tags=System.Object[]; steps=System.Object[]; type=scenario}}
id          : 
keyword     : Feature
line        : 3
tags        : {@{name=automated; line=1}, @{name=WI9; line=1}}
name        : Book details
uri         : Features\Book Details.feature

I am not able to call the individual objects like $json.description etc the only options I get when doing “$json.” are:

  • Count
  • Length
  • LongLength
  • Rank
  • SyncRoot
  • IsReadOnly
  • IsFixedSize
  • IsSynchronized

My Json format is valid so I can’t understand why the conversion is not working properly or maybe it is working and I am just missing something, that is why I am here :smiley: any help would be massively appreciated.

Just for clarity here is my C# code so you can see how I am trying to get it to work:

public class Report : IReport
    {
        public const string FullyQualifiedName = "{0}.{1}.#()::TestAssembly:{2}/Feature:{3}/Scenario:{4}";
        public const string FullyQualifiedNameWithTarget = "{0}.{1}.#()::Target:{2}/TestAssembly:{3}/Feature:{4}/Scenario:{5}";

        public List<string> GetTests(string projectName, string reportPath, string target)
        {
            Deseralize<RootModel> deseralize = new Deseralize<RootModel>();

            List<string> failedTests = new List<string>();
            var reports = deseralize.ReadJson(reportPath);

            reports.SelectMany(report => report.Elements)
                   .SelectMany(step => step.Steps)
                   .Where(step => step.Result.Status == "Failed");

            if(target != null)
            {
                for (int i = 0; i < reports[0].Elements.Count(); i++)
                    failedTests.Add(GetFullyQualifiedName(projectName, reports[0].Name, reports[0].Elements[i].Name, target));
            }
            else
            {
                for (int i = 0; i < reports[0].Elements.Count(); i++)
                    failedTests.Add(GetFullyQualifiedName(projectName, reports[0].Name, reports[0].Elements[i].Name));
            }

            return failedTests;
        }

        public string GetFullyQualifiedName(string project, string feature, string scenario, string target = null)
        {
            if (target != null)
            {
                return string.Format(FullyQualifiedNameWithTarget, project, feature, target, project, HttpUtility.UrlEncode(feature), HttpUtility.UrlEncode(scenario));
            }
            return string.Format(FullyQualifiedName, project, feature, project, HttpUtility.UrlEncode(feature), HttpUtility.UrlEncode(scenario));
        }
    }
    public class Deseralize<T>
    {
        public List<T> ReadJson(string filePath) => JsonConvert.DeserializeObject<List<T>>(File.ReadAllText(filePath));
    }

So all I am doing is Deserializing the Json into an Object list I then have an Object model for each node that I am using to loop through the Objects to find the steps with a status of “Failed”

Herman,
Welcome to the forums

Since your JSON seems to be an array of hierarchical info you may try to access the individual nodes in a loop.
At least I can output some nodes with this:

$json.elements.keyword
# or
$json.elements.name

… or did I get your question wrong?

1 Like

Try changing it to

$json = $Report | ConvertFrom-Json

Thank you Olaf, I think I may have made a mistake here it seems that I can access the objects created by the ConvertFrom-Json but the dot notation was not being automatically set as I expected it to, so I assumed that it wasn’t working. However, as a follow-up question I have seen in online examples where dot notation is automatically generated in the Powershell ISE IntelliSense this would be rather helpful and save a lot of trial and error, is there a way for me to do this?

I actually don’t know what you are talking about. Everything worked for me as expected. Of course you will not get any output from

when this node does not have any content.

Your JSON may be valid but on the other hand it might not be what you expected. :wink: