how to parse json response in powershell
Asked Answered
A

3

18

managed to get the JSON data with

$R= Invoke-WebRequest -Uri $url -Headers $headers -ContentType "application/json"   -Method Get -UseBasicParsing
$x = $R.Content | Out-String | ConvertFrom-Json 

now I've a JSON file like this :

{
  "id": 1000,
  "name_with_namespace": "myProjectName1",

},
{
  "id": 1001,
  "name_with_namespace": "myProjectName2",

},
{
  "id": 1002,
  "name_with_namespace": "myProjectName3",

}

now I need to extract all the occurence of "name_with_namespace" and "id" where "name_with_namespace" = "myProjectName.*"

How can I do it in one shot?

I've tried this:

foreach ($name in $x.name_with_namespace) {
    if ( $name -match ".*myProjectName.*" ) {    
        write-host "$name - $x.id"               
    }   
}

but I got this:

myProjectName1 1000 1001 1002
myProjectName2 1000 1001 1002
myProjectName3 1000 1001 1002

I understand that the issue is on $x.id, how can I get the right value instead of everything ?

my expected output is

myProjectName1 1000
myProjectName2 1001
myProjectName3 1002
Asthenic answered 6/3, 2018 at 16:55 Comment(2)
What is your expected output ? The iteration is considering the child nodes iteration as well. That is why you are getting repetitive IDs. for each parent node. Let me try with itGarfieldgarfinkel
@RanadipDutta I've added it in the main questionAsthenic
T
14

You're drilling down a level too far when you define your loop. Just iterate $x and then check against the specific property inside the loop.

foreach ($name in $x) {
    if ( $name.name_with_namespace -match ".*myProjectName.*" ) {    
        write-host "$($name.name_with_namespace) - $($name.id)"               
    }   
}

Edit: On a side note, you can simplify your -match to just "myProjectName" and it will work just as well, and probably faster.

Thickwitted answered 6/3, 2018 at 17:26 Comment(1)
@ClaudioM: You can do in this way also. However, I was trying to format the proper json TheMadTechnician. Let me know if I have missed out anythingGarfieldgarfinkel
F
3

ConvertFrom-Json has some odd behavior with pipelines. The issue is that ConvertFrom-Json wraps the JSON array in an array and then passes the whole array down the pipeline as one item. This is fine in most cases, but if the outermost level is a JSON array, then that whole array gets passed as a single object into the pipeline.

Compare:

PS> ConvertFrom-Json '[1, 2, 3]' | ForEach-Object  {": $_"}
: 1 2 3

PS> (ConvertFrom-Json '[1, 2, 3]') | ForEach-Object  {": $_"}
: 1
: 2
: 3

PS> $x = ConvertFrom-Json '[1, 2, 3]'
PS> $x | ForEach-Object  {": $_"}
: 1
: 2
: 3
PS> ,$x | ForEach-Object  {": $_"}
: 1 2 3

Note with that last example we can duplicate the problem with the unary comma operator.

The issue has been reported here for PowerShell Core 6.

Try this code:

$j = @'
[
    {
        "id": 1000,
        "name_with_namespace": "myProjectName1"
    },
    {
        "id": 1001,
        "name_with_namespace": "myProjectName2"
    },
    {
        "id": 1002,
        "name_with_namespace": "myProjectName3"
    }
]
'@

($j | Out-String | ConvertFrom-Json) |
Where-Object name_with_namespace -match ".*myProjectName.*" |
ForEach-Object {
    "$($_.name_with_namespace) $($_.id)"
}
Formulary answered 6/3, 2018 at 17:36 Comment(0)
G
1

So basically you have obtained the json with the parentnode already, so I am not covering that part. Assuming that you already have the parent node, then you can directly do this :

$a=@"
{"ParentNode":[
    {"id":1000,"name_with_namespace":"myProjectName"},
    {"id":1001,"name_with_namespace":"myProjectName2"},
    {"id":1002,"name_with_namespace":"myProjectName3"}
]}
"@ 

($a | ConvertFrom-Json).ParentNode

Output:

id name_with_namespace
  -- -------------------
1000 myProjectName      
1001 myProjectName2     
1002 myProjectName3

You can parse however you want. No issue on that part. Make sure that your json is structured one that you are receiving from the restAPI. using dot methods, you can go to any level and you can directly select them using select-object as well.

Hope it helps.

Garfieldgarfinkel answered 6/3, 2018 at 17:21 Comment(4)
but I don't have the "ParentNode", my JSON is exactly how I wrote it...Asthenic
Could you please send me the complete content of $x.Garfieldgarfinkel
Admittedly his JSON in his example is flawed, but his issue really isn't with that portion since he displays that he is able to get values from his variable by property name. All he really needed help with was being able to filter an object by property and retain the entire object instead of only referencing the property to filter and losing the rest of the object. The fact that it is JSON is irrelevant in this case. Like in high school math when they gave you story problems with extra useless information, and you had to determine what all was relevant and just work with that.Thickwitted
@TheMadTechnician: Got it :) But appreciate your answer.Garfieldgarfinkel

© 2022 - 2024 — McMap. All rights reserved.