Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Extend JSON with another in PowerShell

Is there some simple way to extend one JSON file with another and save the output to yet another file using PowerShell? Currently I'm attempting to write a recurrent function that will allow me to do that*, but maybe there is a simpler solution out there?

*iterate over properties of a JSON converted to a PSCustomObject and replace them if needed (actually check my answer below)

Edit: I need to do something similar to what jquery.extend does so, my input is:

{
    "name": "Some name",
    "value": 1,
    "config": {
        "debug": false,
        "output": "c:\\"
    }
}

And

{
    "value": 2,
    "config": {
        "debug": true
    },
    "debug": {
        "log": true
    }
}

And my output is supposed to be:

{
    "name": "Some name",
    "value": 2,
    "config": {
        "debug": true,
        "output": "c:\\"
    },
    "debug": {
        "log": true
    }
}

P.S. Generally I need to write a script that can be run from a batch file and does not require 3rd party libraries (is limited to Windows resources). I tried my luck with Cscript JavaScript, but I decided against using it when I found out, that the only built in method to parse JSON is to eval it.

like image 518
jahu Avatar asked Jan 08 '23 15:01

jahu


1 Answers

After a lot of trial and error I managed to write my recurrent function.

function ExtendJSON($base, $ext)
{
    $propNames = $($ext | Get-Member -MemberType *Property).Name
    foreach ($propName in $propNames) {
        if ($base.PSObject.Properties.Match($propName).Count) {
            if ($base.$propName.GetType().Name -eq "PSCustomObject")
            {
                $base.$propName = ExtendJSON $base.$propName $ext.$propName
            }
            else
            {
                $base.$propName = $ext.$propName
            }
        }
        else
        {
            $base | Add-Member -MemberType NoteProperty -Name $propName -Value $ext.$propName
        }
    }
    return $base
}
$file1 = (Get-Content $args[0]) -join "`n" | ConvertFrom-Json
$file2 = (Get-Content $args[1]) -join "`n" | ConvertFrom-Json
#Out-File produces incorrect encoding
#ExtendJSON $file1 $file2 | ConvertTo-Json | Out-File $args[2]

$output = ExtendJSON $file1 $file2 | ConvertTo-Json
#Save output as BOMless UTF8
[System.IO.File]::WriteAllLines($args[2], $output)

I have no idea if this is the easiest way to achieve my goal, but it does get the job done. This also doubles as answer to the how to combine\combine\merge two PSCustomObjects, which appears no one has asked yet (maybe I'm breaching open doors here). I'm nearly inclined to rewrite the question as such, but my gut is telling me there might be different methods of extending JSON using PowerShell, which don't necessarily require converting my JSON files to PSCustomObject.

like image 58
jahu Avatar answered Jan 16 '23 17:01

jahu