0

I am working on one challenge which I am trying to solve, but due to lack of experience hit a roadblock. I would greatly appreciate any help from gurus on this site :)

I need to convert JSON input to property format. Example: Given JSON:

{
  "name": "John",
  "age": 30,
  "married": True,
  "cars": [
    {"model": "BMW 230", "mpg": 27.5},
    {"model": "Ford Edge", "mpg": 24.1}
  ]}

Need to be converted to following format once script executed:

name="John"
age=30
married=true
cars.0.model="BMW 230"
cars.0.mpg=27.5
cars.1.model="Ford Edge"
cars.1.mpg=24.1

I found this online converter which works: https://tools.fromdev.com/json-to-property-converter.html

But because in my case i need to integrate to Azure pipeline, online version will not work for me

Any help would be greatly appreciated!

2
  • 1
    I believe JSON booleans are supposed to be lowercase. What have you tried? Commented Jun 29, 2021 at 16:40
  • Answer below solved my problem. The goal of this was to automate azure pipeline deployment, so i can parse json and use it in variable sets: learn.microsoft.com/en-us/azure/devops/pipelines/tasks/… Commented Jun 29, 2021 at 20:23

1 Answer 1

1

This kind of format with the equals sign and no further punctuation is called StringData format in PowerShell and elsewhere.

PowerShell acutally already has a ConvertFrom-StringData function, but not a ConvertTo-StringData function.

However, we can make our own but it requires a few helper functions to do it.

I thought this was interesting so I took a stab at it today.

Here's what the calling function looks like:

Function ConvertTo-StringData($object, $propertyOverride){
    $fields = $object | get-member -MemberType NoteProperty
    foreach($field in $fields){
        if (IsArray($field)){
             OutputArrayMember -object $object -field $field
             
        }
        else{
            OutputMember -object $object -propertyName $field.name -propertyOverride $propertyOverride
        }
    }
}

It depends on these helper functions to work.

Function IsArray($object){
    $object.Definition -match '.*\[\].*'
}

Function OutputMember($object,$propertyName, $propertyOverride){
    if ($propertyOverride){
        "$($propertyOverride).$($propertyName)=$($object.$($propertyName))"
    }
    else{
       "$($propertyName)=$($object.$($propertyName))"
    }
     
}

Function OutputArrayMember($object, $field){
    $base = $field.Name
    $i = 0 
    foreach ($item in $object.$($field.Name)){
        ConvertTo-StringData -object $object.$($field.Name)[$i] -propertyOverride "$base[$i]"
        $i++
    }
    
}

And here's the output:

enter image description here

Here's the full code as a github gist, for posterity.

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

5 Comments

WOW! Thank you so much! I have a quick question: in there a way to get dot instead of square brackets? cars[1].mpg=24.1 => cars.1.mpg=24.1
Just figured it out. Made a small change here: ConvertTo-StringData -object $object.$($field.Name)[$i] -propertyOverride "$base.$i"
While testing found small issue. Code will not work if more complex json is used ``` { "Logging": { "LogLevel": { "Default": "None", "Microsoft": "Warning", "Microsoft.Hosting.Lifetime": "None", "System.Net.Http.HttpClient.SDSEmployeeMaster.ClientHandler[100]": "None" } } } ``` Should return: Logging.LogLevel.Default=None Logging.LogLevel.Microsoft=Warning Logging.LogLevel.Microsoft.Hosting.Lifetime=None Logging.LogLevel.System.Net.Http.HttpClient.SDSEmployeeMaster.ClientHandler[100]=None
If you know one or more properties are deeply nested, they will still work with this cmdlet. Call it like this: convertto-stringdata $json.Logging.LogLevel -propertyOverride Logging.Loglevel . You could use special handling like this to achieve your goal for anything nested more than two nodes. Feel free to edit the code for your purposes
Thank you for quick response! In my case JSON structure is dynamic and i can not hard code values :(. I am trying to find a way to modify code so it can work on any Json and produce desired result. If i succeed i will share result here :)

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.