Powershell: How to dynamically update a nested JSON array?Powershell: How to Update/Replace data and values in Json and XML ObjectSet Value of Nested Object Property by Name in PowerShellHow do I format a Microsoft JSON date?How do I check if an array includes an object in JavaScript?How to append something to an array?How can I pretty-print JSON in a shell script?How to insert an item into an array at a specific index (JavaScript)?How do I determine whether an array contains a particular value in Java?How do I empty an array in JavaScript?How to check if an object is an array?How do I remove a particular element from an array in JavaScript?How do I POST JSON data with Curl from a terminal/commandline to Test Spring REST?

How to switch an 80286 from protected to real mode?

Getting an entry level IT position later in life

Responding to Plague Engineer

How to approach protecting my code as a research assistant? Should I be worried in the first place?

Find only those folders that contain a File with the same name as the Folder

Did Apollo leave poop on the moon?

Can this code, to convert string to integer, be made more compact?

Based on what criteria do you add/not add icons to labels within a toolbar?

monolingual dictionary

Which genus do I use for neutral expressions in German?

Minors holding dual citizenship - using Canadian passport to enter/exit US

Best way to explain to my boss that I cannot attend a team summit because it is on Rosh Hashana or any other Jewish Holiday

Can chords be inferred from melody alone?

Is it double speak?

Unexpected route on a flight from USA to Europe

Does the length of a password for Wi-Fi affect speed?

Did silent film actors actually say their lines or did they simply improvise “dialogue” while being filmed?

Is space radiation a risk for space film photography, and how is this prevented?

How would a family travel from Indiana to Texas in 1911?

What are the examples (applications) of the MIPs in which the objective function has nonzero coefficients for only continuous variables?

Does this put me at risk for identity theft?

How to realistically deal with a shield user?

Validation and verification of mathematical models

Can a Hogwarts student refuse the Sorting Hat's decision?



Powershell: How to dynamically update a nested JSON array?


Powershell: How to Update/Replace data and values in Json and XML ObjectSet Value of Nested Object Property by Name in PowerShellHow do I format a Microsoft JSON date?How do I check if an array includes an object in JavaScript?How to append something to an array?How can I pretty-print JSON in a shell script?How to insert an item into an array at a specific index (JavaScript)?How do I determine whether an array contains a particular value in Java?How do I empty an array in JavaScript?How to check if an object is an array?How do I remove a particular element from an array in JavaScript?How do I POST JSON data with Curl from a terminal/commandline to Test Spring REST?






.everyoneloves__top-leaderboard:empty,.everyoneloves__mid-leaderboard:empty,.everyoneloves__bot-mid-leaderboard:empty margin-bottom:0;








2















What I'm trying to do is take any well-formed JSON file/object and search for a path inside it. If the path isn't found, move on. If it is found, update the value. Once updated, save the updated JSON to the original file.



The catch to this, is the well-formed JSON structure is not known ahead of time. It's possible I might be searching hundreds of .json files on a disk, so the files that don't match any of my search terms can just be ignored.



I'm struggling to wrap my head around how to solve this problem. Most of the examples out there don't have a JSON object with an array for one of the key values, or they don't access the properties dynamically when an array is involved.



This link: Powershell: How to Update/Replace data and values in Json and XML Object shows a (sort of)"real" JSON structure, but the accepted answer relies on knowing what the JSON structure is (the OP didn't ask for help with dynamic pathing).



This link: Set Value of Nested Object Property by Name in PowerShell has something very close, although when an array is in the mix, it doesn't work properly when setting.



Here's some example JSON to use with this problem, though again, the structure is not known before the script runs. I'm looping over a list of files on disk, and executing for each file.



$JSON = ConvertFrom-Json '
"key1":"key 1 value",
"options":
"outDir":"./app-dir",
"lib":[
"someLibrary",
"anotherLibrary"
],
"someObjects":[

"first":"I am first"
,

"second":"I am second"

]

'


The string to search this json might look like the following:



$SearchString = 'options.someObjects.first'


Or perhaps, something non-existent like:



$SearchString = 'options.someObjects.foo'


Using the recursive function GetValue from the 2nd article works beautifully for getting (and much more elegant than what I was doing):



function GetValue($object, $key)

$p1,$p2 = $key.Split(".")
if($p2) return GetValue -object $object.$p1 -key $p2
else return $object.$p1



However, the function SetValue does not work with an array. It returns an error stating "The property 'first' can not be found on this object."



function SetValue($object, $key, $Value)

$p1,$p2 = $key.Split(".")
if($p2) SetValue -object $object.$p1 -key $p2 -Value $Value
else $object.$p1 = $Value



I am aware this is because $JSON.options.someObjects is an array, therefore to access the object with the "first" key, the path would be:



$JSON.options.someObjects[0].first


That's the problem I'm having. How do I dynamically iterate over all objects once it reaches a part of the path that needs iterating? That part of the path could be anywhere, or more levels down, etc...



It's strange that powershell will allow you to dynamically iterate through an array when getting the value, but not when trying to set it.



Here's a complete example which demonstrates the entire issue:



#Create JSON:
$JSON = ConvertFrom-Json '
"key1":"key 1 value",
"options":
"outDir":"./app-dir",
"lib":[
"someLibrary",
"anotherLibrary"
],
"someObjects":[

"first":"I am first"
,

"second":"I am second"

]

'


$SearchPath = 'options.someObjects.first'
$NewValue = 'I am a new value'

function GetValue($object, $key)

$p1,$p2 = $key.Split(".")
if($p2) GetValue -object $object.$p1 -key $p2
else return $object.$p1


function SetValue($object, $key, $Value)

$p1,$p2 = $key.Split(".")
if($p2) SetValue -object $object.$p1 -key $p2 -Value $Value
else return $object.$p1 = $Value



GetValue -object $JSON -key $SearchPath

SetValue -object $JSON -key $SearchPath -Value $NewValue


I've been searching all kinds of different terms trying to arrive at a good solution for this problem, but so far, no luck. I'm fairly certain I'm not the 1st person to want to do this sort of thing, apologies if I missed the answer somewhere.










share|improve this question
























  • May I suggest another approach? JSON is basically just strings. I believe that you would be able to solve this with some regex and replace patterns. Do you ONLY know the value that you need to replace? Or do you know the property name also? Like is the property name always the same, regardless what nested level we are at?

    – Mötz
    Mar 27 at 8:45












  • Yes, actually I started tackling this issue using regex. The problem with that approach is some of the maintainers of the "search strings" are not the most techie of people and regex, while very useful for this, would mean that I would need to maintain the list (what I'm trying to avoid).In the end, I will have a csv file with the search path and the new value which this script will load up and apply to a number of different files.

    – diggity
    Mar 27 at 13:39


















2















What I'm trying to do is take any well-formed JSON file/object and search for a path inside it. If the path isn't found, move on. If it is found, update the value. Once updated, save the updated JSON to the original file.



The catch to this, is the well-formed JSON structure is not known ahead of time. It's possible I might be searching hundreds of .json files on a disk, so the files that don't match any of my search terms can just be ignored.



I'm struggling to wrap my head around how to solve this problem. Most of the examples out there don't have a JSON object with an array for one of the key values, or they don't access the properties dynamically when an array is involved.



This link: Powershell: How to Update/Replace data and values in Json and XML Object shows a (sort of)"real" JSON structure, but the accepted answer relies on knowing what the JSON structure is (the OP didn't ask for help with dynamic pathing).



This link: Set Value of Nested Object Property by Name in PowerShell has something very close, although when an array is in the mix, it doesn't work properly when setting.



Here's some example JSON to use with this problem, though again, the structure is not known before the script runs. I'm looping over a list of files on disk, and executing for each file.



$JSON = ConvertFrom-Json '
"key1":"key 1 value",
"options":
"outDir":"./app-dir",
"lib":[
"someLibrary",
"anotherLibrary"
],
"someObjects":[

"first":"I am first"
,

"second":"I am second"

]

'


The string to search this json might look like the following:



$SearchString = 'options.someObjects.first'


Or perhaps, something non-existent like:



$SearchString = 'options.someObjects.foo'


Using the recursive function GetValue from the 2nd article works beautifully for getting (and much more elegant than what I was doing):



function GetValue($object, $key)

$p1,$p2 = $key.Split(".")
if($p2) return GetValue -object $object.$p1 -key $p2
else return $object.$p1



However, the function SetValue does not work with an array. It returns an error stating "The property 'first' can not be found on this object."



function SetValue($object, $key, $Value)

$p1,$p2 = $key.Split(".")
if($p2) SetValue -object $object.$p1 -key $p2 -Value $Value
else $object.$p1 = $Value



I am aware this is because $JSON.options.someObjects is an array, therefore to access the object with the "first" key, the path would be:



$JSON.options.someObjects[0].first


That's the problem I'm having. How do I dynamically iterate over all objects once it reaches a part of the path that needs iterating? That part of the path could be anywhere, or more levels down, etc...



It's strange that powershell will allow you to dynamically iterate through an array when getting the value, but not when trying to set it.



Here's a complete example which demonstrates the entire issue:



#Create JSON:
$JSON = ConvertFrom-Json '
"key1":"key 1 value",
"options":
"outDir":"./app-dir",
"lib":[
"someLibrary",
"anotherLibrary"
],
"someObjects":[

"first":"I am first"
,

"second":"I am second"

]

'


$SearchPath = 'options.someObjects.first'
$NewValue = 'I am a new value'

function GetValue($object, $key)

$p1,$p2 = $key.Split(".")
if($p2) GetValue -object $object.$p1 -key $p2
else return $object.$p1


function SetValue($object, $key, $Value)

$p1,$p2 = $key.Split(".")
if($p2) SetValue -object $object.$p1 -key $p2 -Value $Value
else return $object.$p1 = $Value



GetValue -object $JSON -key $SearchPath

SetValue -object $JSON -key $SearchPath -Value $NewValue


I've been searching all kinds of different terms trying to arrive at a good solution for this problem, but so far, no luck. I'm fairly certain I'm not the 1st person to want to do this sort of thing, apologies if I missed the answer somewhere.










share|improve this question
























  • May I suggest another approach? JSON is basically just strings. I believe that you would be able to solve this with some regex and replace patterns. Do you ONLY know the value that you need to replace? Or do you know the property name also? Like is the property name always the same, regardless what nested level we are at?

    – Mötz
    Mar 27 at 8:45












  • Yes, actually I started tackling this issue using regex. The problem with that approach is some of the maintainers of the "search strings" are not the most techie of people and regex, while very useful for this, would mean that I would need to maintain the list (what I'm trying to avoid).In the end, I will have a csv file with the search path and the new value which this script will load up and apply to a number of different files.

    – diggity
    Mar 27 at 13:39














2












2








2








What I'm trying to do is take any well-formed JSON file/object and search for a path inside it. If the path isn't found, move on. If it is found, update the value. Once updated, save the updated JSON to the original file.



The catch to this, is the well-formed JSON structure is not known ahead of time. It's possible I might be searching hundreds of .json files on a disk, so the files that don't match any of my search terms can just be ignored.



I'm struggling to wrap my head around how to solve this problem. Most of the examples out there don't have a JSON object with an array for one of the key values, or they don't access the properties dynamically when an array is involved.



This link: Powershell: How to Update/Replace data and values in Json and XML Object shows a (sort of)"real" JSON structure, but the accepted answer relies on knowing what the JSON structure is (the OP didn't ask for help with dynamic pathing).



This link: Set Value of Nested Object Property by Name in PowerShell has something very close, although when an array is in the mix, it doesn't work properly when setting.



Here's some example JSON to use with this problem, though again, the structure is not known before the script runs. I'm looping over a list of files on disk, and executing for each file.



$JSON = ConvertFrom-Json '
"key1":"key 1 value",
"options":
"outDir":"./app-dir",
"lib":[
"someLibrary",
"anotherLibrary"
],
"someObjects":[

"first":"I am first"
,

"second":"I am second"

]

'


The string to search this json might look like the following:



$SearchString = 'options.someObjects.first'


Or perhaps, something non-existent like:



$SearchString = 'options.someObjects.foo'


Using the recursive function GetValue from the 2nd article works beautifully for getting (and much more elegant than what I was doing):



function GetValue($object, $key)

$p1,$p2 = $key.Split(".")
if($p2) return GetValue -object $object.$p1 -key $p2
else return $object.$p1



However, the function SetValue does not work with an array. It returns an error stating "The property 'first' can not be found on this object."



function SetValue($object, $key, $Value)

$p1,$p2 = $key.Split(".")
if($p2) SetValue -object $object.$p1 -key $p2 -Value $Value
else $object.$p1 = $Value



I am aware this is because $JSON.options.someObjects is an array, therefore to access the object with the "first" key, the path would be:



$JSON.options.someObjects[0].first


That's the problem I'm having. How do I dynamically iterate over all objects once it reaches a part of the path that needs iterating? That part of the path could be anywhere, or more levels down, etc...



It's strange that powershell will allow you to dynamically iterate through an array when getting the value, but not when trying to set it.



Here's a complete example which demonstrates the entire issue:



#Create JSON:
$JSON = ConvertFrom-Json '
"key1":"key 1 value",
"options":
"outDir":"./app-dir",
"lib":[
"someLibrary",
"anotherLibrary"
],
"someObjects":[

"first":"I am first"
,

"second":"I am second"

]

'


$SearchPath = 'options.someObjects.first'
$NewValue = 'I am a new value'

function GetValue($object, $key)

$p1,$p2 = $key.Split(".")
if($p2) GetValue -object $object.$p1 -key $p2
else return $object.$p1


function SetValue($object, $key, $Value)

$p1,$p2 = $key.Split(".")
if($p2) SetValue -object $object.$p1 -key $p2 -Value $Value
else return $object.$p1 = $Value



GetValue -object $JSON -key $SearchPath

SetValue -object $JSON -key $SearchPath -Value $NewValue


I've been searching all kinds of different terms trying to arrive at a good solution for this problem, but so far, no luck. I'm fairly certain I'm not the 1st person to want to do this sort of thing, apologies if I missed the answer somewhere.










share|improve this question














What I'm trying to do is take any well-formed JSON file/object and search for a path inside it. If the path isn't found, move on. If it is found, update the value. Once updated, save the updated JSON to the original file.



The catch to this, is the well-formed JSON structure is not known ahead of time. It's possible I might be searching hundreds of .json files on a disk, so the files that don't match any of my search terms can just be ignored.



I'm struggling to wrap my head around how to solve this problem. Most of the examples out there don't have a JSON object with an array for one of the key values, or they don't access the properties dynamically when an array is involved.



This link: Powershell: How to Update/Replace data and values in Json and XML Object shows a (sort of)"real" JSON structure, but the accepted answer relies on knowing what the JSON structure is (the OP didn't ask for help with dynamic pathing).



This link: Set Value of Nested Object Property by Name in PowerShell has something very close, although when an array is in the mix, it doesn't work properly when setting.



Here's some example JSON to use with this problem, though again, the structure is not known before the script runs. I'm looping over a list of files on disk, and executing for each file.



$JSON = ConvertFrom-Json '
"key1":"key 1 value",
"options":
"outDir":"./app-dir",
"lib":[
"someLibrary",
"anotherLibrary"
],
"someObjects":[

"first":"I am first"
,

"second":"I am second"

]

'


The string to search this json might look like the following:



$SearchString = 'options.someObjects.first'


Or perhaps, something non-existent like:



$SearchString = 'options.someObjects.foo'


Using the recursive function GetValue from the 2nd article works beautifully for getting (and much more elegant than what I was doing):



function GetValue($object, $key)

$p1,$p2 = $key.Split(".")
if($p2) return GetValue -object $object.$p1 -key $p2
else return $object.$p1



However, the function SetValue does not work with an array. It returns an error stating "The property 'first' can not be found on this object."



function SetValue($object, $key, $Value)

$p1,$p2 = $key.Split(".")
if($p2) SetValue -object $object.$p1 -key $p2 -Value $Value
else $object.$p1 = $Value



I am aware this is because $JSON.options.someObjects is an array, therefore to access the object with the "first" key, the path would be:



$JSON.options.someObjects[0].first


That's the problem I'm having. How do I dynamically iterate over all objects once it reaches a part of the path that needs iterating? That part of the path could be anywhere, or more levels down, etc...



It's strange that powershell will allow you to dynamically iterate through an array when getting the value, but not when trying to set it.



Here's a complete example which demonstrates the entire issue:



#Create JSON:
$JSON = ConvertFrom-Json '
"key1":"key 1 value",
"options":
"outDir":"./app-dir",
"lib":[
"someLibrary",
"anotherLibrary"
],
"someObjects":[

"first":"I am first"
,

"second":"I am second"

]

'


$SearchPath = 'options.someObjects.first'
$NewValue = 'I am a new value'

function GetValue($object, $key)

$p1,$p2 = $key.Split(".")
if($p2) GetValue -object $object.$p1 -key $p2
else return $object.$p1


function SetValue($object, $key, $Value)

$p1,$p2 = $key.Split(".")
if($p2) SetValue -object $object.$p1 -key $p2 -Value $Value
else return $object.$p1 = $Value



GetValue -object $JSON -key $SearchPath

SetValue -object $JSON -key $SearchPath -Value $NewValue


I've been searching all kinds of different terms trying to arrive at a good solution for this problem, but so far, no luck. I'm fairly certain I'm not the 1st person to want to do this sort of thing, apologies if I missed the answer somewhere.







arrays json powershell nested






share|improve this question













share|improve this question











share|improve this question




share|improve this question










asked Mar 27 at 4:37









diggitydiggity

132 bronze badges




132 bronze badges















  • May I suggest another approach? JSON is basically just strings. I believe that you would be able to solve this with some regex and replace patterns. Do you ONLY know the value that you need to replace? Or do you know the property name also? Like is the property name always the same, regardless what nested level we are at?

    – Mötz
    Mar 27 at 8:45












  • Yes, actually I started tackling this issue using regex. The problem with that approach is some of the maintainers of the "search strings" are not the most techie of people and regex, while very useful for this, would mean that I would need to maintain the list (what I'm trying to avoid).In the end, I will have a csv file with the search path and the new value which this script will load up and apply to a number of different files.

    – diggity
    Mar 27 at 13:39


















  • May I suggest another approach? JSON is basically just strings. I believe that you would be able to solve this with some regex and replace patterns. Do you ONLY know the value that you need to replace? Or do you know the property name also? Like is the property name always the same, regardless what nested level we are at?

    – Mötz
    Mar 27 at 8:45












  • Yes, actually I started tackling this issue using regex. The problem with that approach is some of the maintainers of the "search strings" are not the most techie of people and regex, while very useful for this, would mean that I would need to maintain the list (what I'm trying to avoid).In the end, I will have a csv file with the search path and the new value which this script will load up and apply to a number of different files.

    – diggity
    Mar 27 at 13:39

















May I suggest another approach? JSON is basically just strings. I believe that you would be able to solve this with some regex and replace patterns. Do you ONLY know the value that you need to replace? Or do you know the property name also? Like is the property name always the same, regardless what nested level we are at?

– Mötz
Mar 27 at 8:45






May I suggest another approach? JSON is basically just strings. I believe that you would be able to solve this with some regex and replace patterns. Do you ONLY know the value that you need to replace? Or do you know the property name also? Like is the property name always the same, regardless what nested level we are at?

– Mötz
Mar 27 at 8:45














Yes, actually I started tackling this issue using regex. The problem with that approach is some of the maintainers of the "search strings" are not the most techie of people and regex, while very useful for this, would mean that I would need to maintain the list (what I'm trying to avoid).In the end, I will have a csv file with the search path and the new value which this script will load up and apply to a number of different files.

– diggity
Mar 27 at 13:39






Yes, actually I started tackling this issue using regex. The problem with that approach is some of the maintainers of the "search strings" are not the most techie of people and regex, while very useful for this, would mean that I would need to maintain the list (what I'm trying to avoid).In the end, I will have a csv file with the search path and the new value which this script will load up and apply to a number of different files.

– diggity
Mar 27 at 13:39













1 Answer
1






active

oldest

votes


















2














There are two issues with your SetValue script:



  • Returning the object

  • An Object ([Object]) vs an object array
    ([Object[]])

Return



You can't return an assignment like return $object.$p1 = $Value. The assignment itself returns nothing with will result in returning a $Null to caller.

Besides, if you return the $Object for each recursive call, you will need to void ($Null = SetValue -object...) it by each parent caller so that it is only returned by the top caller. but keep in mind that you are actually poking the $NewValue in the original ($JSON) object!. If you don't want that, you will need to figure out the top caller and only copy the $Object at the top level before the recursive call.



Object array



You not just dealing with properties containing single objects but each property might potentially contain a collection objects. In fact, the leaf property SomeObject is an example of this. Meaning that each object in the collection has its own unique set of properties (which could have the same property name as the sibling object):



$JSON = ConvertFrom-Json '
"key1":"key 1 value",
"options":
"outDir":"./app-dir",
"lib":[
"someLibrary",
"anotherLibrary"
],
"someObjects":[

"first":"I am first"
,

"first":"I am first too"
,

"second":"I am second"

]

'


Note that you might actually encounter a object collection at every level of the Json object.

Since PSv3 you have a feature called Member Enumeration which lets you list these properties in ones, like: ([Object[]]$SomeObject).First but you can't just set (all) the concerned properties like this: ([Object[]]$SomeObject).First = $Value. (That is why your SetValue function doesn't work and your GetValue function does. Note that it
actually returns two items for the above "I am first too" Json example).



Answer



In other words, you will need to iterate through all the object collections on each level to set the concerned property:



function SetValue($object, $key, $Value)

$p1,$p2 = $key.Split(".",2)
if($p2) %SetValue -object $_.$p1 -key $p2 -Value $Value
else ?$Null -ne $_.$p1


SetValue -object $JSON -key $SearchPath -Value $NewValue

$Json | ConvertTo-Json -Depth 5

"key1": "key 1 value",
"options":
"outDir": "./app-dir",
"lib": [
"someLibrary",
"anotherLibrary"
],
"someObjects": [

"first": "I am a new value"
,

"second": "I am second"

]







share|improve this answer



























  • Thanks @iRon ! Also thank you for including the link to (and explaining) member enumeration. So far so good with your function. This is an excellent building block for the overall project.

    – diggity
    Mar 27 at 14:27











Your Answer






StackExchange.ifUsing("editor", function ()
StackExchange.using("externalEditor", function ()
StackExchange.using("snippets", function ()
StackExchange.snippets.init();
);
);
, "code-snippets");

StackExchange.ready(function()
var channelOptions =
tags: "".split(" "),
id: "1"
;
initTagRenderer("".split(" "), "".split(" "), channelOptions);

StackExchange.using("externalEditor", function()
// Have to fire editor after snippets, if snippets enabled
if (StackExchange.settings.snippets.snippetsEnabled)
StackExchange.using("snippets", function()
createEditor();
);

else
createEditor();

);

function createEditor()
StackExchange.prepareEditor(
heartbeatType: 'answer',
autoActivateHeartbeat: false,
convertImagesToLinks: true,
noModals: true,
showLowRepImageUploadWarning: true,
reputationToPostImages: 10,
bindNavPrevention: true,
postfix: "",
imageUploader:
brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
allowUrls: true
,
onDemand: true,
discardSelector: ".discard-answer"
,immediatelyShowMarkdownHelp:true
);



);













draft saved

draft discarded


















StackExchange.ready(
function ()
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f55369899%2fpowershell-how-to-dynamically-update-a-nested-json-array%23new-answer', 'question_page');

);

Post as a guest















Required, but never shown

























1 Answer
1






active

oldest

votes








1 Answer
1






active

oldest

votes









active

oldest

votes






active

oldest

votes









2














There are two issues with your SetValue script:



  • Returning the object

  • An Object ([Object]) vs an object array
    ([Object[]])

Return



You can't return an assignment like return $object.$p1 = $Value. The assignment itself returns nothing with will result in returning a $Null to caller.

Besides, if you return the $Object for each recursive call, you will need to void ($Null = SetValue -object...) it by each parent caller so that it is only returned by the top caller. but keep in mind that you are actually poking the $NewValue in the original ($JSON) object!. If you don't want that, you will need to figure out the top caller and only copy the $Object at the top level before the recursive call.



Object array



You not just dealing with properties containing single objects but each property might potentially contain a collection objects. In fact, the leaf property SomeObject is an example of this. Meaning that each object in the collection has its own unique set of properties (which could have the same property name as the sibling object):



$JSON = ConvertFrom-Json '
"key1":"key 1 value",
"options":
"outDir":"./app-dir",
"lib":[
"someLibrary",
"anotherLibrary"
],
"someObjects":[

"first":"I am first"
,

"first":"I am first too"
,

"second":"I am second"

]

'


Note that you might actually encounter a object collection at every level of the Json object.

Since PSv3 you have a feature called Member Enumeration which lets you list these properties in ones, like: ([Object[]]$SomeObject).First but you can't just set (all) the concerned properties like this: ([Object[]]$SomeObject).First = $Value. (That is why your SetValue function doesn't work and your GetValue function does. Note that it
actually returns two items for the above "I am first too" Json example).



Answer



In other words, you will need to iterate through all the object collections on each level to set the concerned property:



function SetValue($object, $key, $Value)

$p1,$p2 = $key.Split(".",2)
if($p2) %SetValue -object $_.$p1 -key $p2 -Value $Value
else ?$Null -ne $_.$p1


SetValue -object $JSON -key $SearchPath -Value $NewValue

$Json | ConvertTo-Json -Depth 5

"key1": "key 1 value",
"options":
"outDir": "./app-dir",
"lib": [
"someLibrary",
"anotherLibrary"
],
"someObjects": [

"first": "I am a new value"
,

"second": "I am second"

]







share|improve this answer



























  • Thanks @iRon ! Also thank you for including the link to (and explaining) member enumeration. So far so good with your function. This is an excellent building block for the overall project.

    – diggity
    Mar 27 at 14:27
















2














There are two issues with your SetValue script:



  • Returning the object

  • An Object ([Object]) vs an object array
    ([Object[]])

Return



You can't return an assignment like return $object.$p1 = $Value. The assignment itself returns nothing with will result in returning a $Null to caller.

Besides, if you return the $Object for each recursive call, you will need to void ($Null = SetValue -object...) it by each parent caller so that it is only returned by the top caller. but keep in mind that you are actually poking the $NewValue in the original ($JSON) object!. If you don't want that, you will need to figure out the top caller and only copy the $Object at the top level before the recursive call.



Object array



You not just dealing with properties containing single objects but each property might potentially contain a collection objects. In fact, the leaf property SomeObject is an example of this. Meaning that each object in the collection has its own unique set of properties (which could have the same property name as the sibling object):



$JSON = ConvertFrom-Json '
"key1":"key 1 value",
"options":
"outDir":"./app-dir",
"lib":[
"someLibrary",
"anotherLibrary"
],
"someObjects":[

"first":"I am first"
,

"first":"I am first too"
,

"second":"I am second"

]

'


Note that you might actually encounter a object collection at every level of the Json object.

Since PSv3 you have a feature called Member Enumeration which lets you list these properties in ones, like: ([Object[]]$SomeObject).First but you can't just set (all) the concerned properties like this: ([Object[]]$SomeObject).First = $Value. (That is why your SetValue function doesn't work and your GetValue function does. Note that it
actually returns two items for the above "I am first too" Json example).



Answer



In other words, you will need to iterate through all the object collections on each level to set the concerned property:



function SetValue($object, $key, $Value)

$p1,$p2 = $key.Split(".",2)
if($p2) %SetValue -object $_.$p1 -key $p2 -Value $Value
else ?$Null -ne $_.$p1


SetValue -object $JSON -key $SearchPath -Value $NewValue

$Json | ConvertTo-Json -Depth 5

"key1": "key 1 value",
"options":
"outDir": "./app-dir",
"lib": [
"someLibrary",
"anotherLibrary"
],
"someObjects": [

"first": "I am a new value"
,

"second": "I am second"

]







share|improve this answer



























  • Thanks @iRon ! Also thank you for including the link to (and explaining) member enumeration. So far so good with your function. This is an excellent building block for the overall project.

    – diggity
    Mar 27 at 14:27














2












2








2







There are two issues with your SetValue script:



  • Returning the object

  • An Object ([Object]) vs an object array
    ([Object[]])

Return



You can't return an assignment like return $object.$p1 = $Value. The assignment itself returns nothing with will result in returning a $Null to caller.

Besides, if you return the $Object for each recursive call, you will need to void ($Null = SetValue -object...) it by each parent caller so that it is only returned by the top caller. but keep in mind that you are actually poking the $NewValue in the original ($JSON) object!. If you don't want that, you will need to figure out the top caller and only copy the $Object at the top level before the recursive call.



Object array



You not just dealing with properties containing single objects but each property might potentially contain a collection objects. In fact, the leaf property SomeObject is an example of this. Meaning that each object in the collection has its own unique set of properties (which could have the same property name as the sibling object):



$JSON = ConvertFrom-Json '
"key1":"key 1 value",
"options":
"outDir":"./app-dir",
"lib":[
"someLibrary",
"anotherLibrary"
],
"someObjects":[

"first":"I am first"
,

"first":"I am first too"
,

"second":"I am second"

]

'


Note that you might actually encounter a object collection at every level of the Json object.

Since PSv3 you have a feature called Member Enumeration which lets you list these properties in ones, like: ([Object[]]$SomeObject).First but you can't just set (all) the concerned properties like this: ([Object[]]$SomeObject).First = $Value. (That is why your SetValue function doesn't work and your GetValue function does. Note that it
actually returns two items for the above "I am first too" Json example).



Answer



In other words, you will need to iterate through all the object collections on each level to set the concerned property:



function SetValue($object, $key, $Value)

$p1,$p2 = $key.Split(".",2)
if($p2) %SetValue -object $_.$p1 -key $p2 -Value $Value
else ?$Null -ne $_.$p1


SetValue -object $JSON -key $SearchPath -Value $NewValue

$Json | ConvertTo-Json -Depth 5

"key1": "key 1 value",
"options":
"outDir": "./app-dir",
"lib": [
"someLibrary",
"anotherLibrary"
],
"someObjects": [

"first": "I am a new value"
,

"second": "I am second"

]







share|improve this answer















There are two issues with your SetValue script:



  • Returning the object

  • An Object ([Object]) vs an object array
    ([Object[]])

Return



You can't return an assignment like return $object.$p1 = $Value. The assignment itself returns nothing with will result in returning a $Null to caller.

Besides, if you return the $Object for each recursive call, you will need to void ($Null = SetValue -object...) it by each parent caller so that it is only returned by the top caller. but keep in mind that you are actually poking the $NewValue in the original ($JSON) object!. If you don't want that, you will need to figure out the top caller and only copy the $Object at the top level before the recursive call.



Object array



You not just dealing with properties containing single objects but each property might potentially contain a collection objects. In fact, the leaf property SomeObject is an example of this. Meaning that each object in the collection has its own unique set of properties (which could have the same property name as the sibling object):



$JSON = ConvertFrom-Json '
"key1":"key 1 value",
"options":
"outDir":"./app-dir",
"lib":[
"someLibrary",
"anotherLibrary"
],
"someObjects":[

"first":"I am first"
,

"first":"I am first too"
,

"second":"I am second"

]

'


Note that you might actually encounter a object collection at every level of the Json object.

Since PSv3 you have a feature called Member Enumeration which lets you list these properties in ones, like: ([Object[]]$SomeObject).First but you can't just set (all) the concerned properties like this: ([Object[]]$SomeObject).First = $Value. (That is why your SetValue function doesn't work and your GetValue function does. Note that it
actually returns two items for the above "I am first too" Json example).



Answer



In other words, you will need to iterate through all the object collections on each level to set the concerned property:



function SetValue($object, $key, $Value)

$p1,$p2 = $key.Split(".",2)
if($p2) %SetValue -object $_.$p1 -key $p2 -Value $Value
else ?$Null -ne $_.$p1


SetValue -object $JSON -key $SearchPath -Value $NewValue

$Json | ConvertTo-Json -Depth 5

"key1": "key 1 value",
"options":
"outDir": "./app-dir",
"lib": [
"someLibrary",
"anotherLibrary"
],
"someObjects": [

"first": "I am a new value"
,

"second": "I am second"

]








share|improve this answer














share|improve this answer



share|improve this answer








edited Mar 27 at 13:37

























answered Mar 27 at 8:58









iRoniRon

5,3552 gold badges25 silver badges38 bronze badges




5,3552 gold badges25 silver badges38 bronze badges















  • Thanks @iRon ! Also thank you for including the link to (and explaining) member enumeration. So far so good with your function. This is an excellent building block for the overall project.

    – diggity
    Mar 27 at 14:27


















  • Thanks @iRon ! Also thank you for including the link to (and explaining) member enumeration. So far so good with your function. This is an excellent building block for the overall project.

    – diggity
    Mar 27 at 14:27

















Thanks @iRon ! Also thank you for including the link to (and explaining) member enumeration. So far so good with your function. This is an excellent building block for the overall project.

– diggity
Mar 27 at 14:27






Thanks @iRon ! Also thank you for including the link to (and explaining) member enumeration. So far so good with your function. This is an excellent building block for the overall project.

– diggity
Mar 27 at 14:27









Got a question that you can’t ask on public Stack Overflow? Learn more about sharing private information with Stack Overflow for Teams.







Got a question that you can’t ask on public Stack Overflow? Learn more about sharing private information with Stack Overflow for Teams.



















draft saved

draft discarded
















































Thanks for contributing an answer to Stack Overflow!


  • Please be sure to answer the question. Provide details and share your research!

But avoid


  • Asking for help, clarification, or responding to other answers.

  • Making statements based on opinion; back them up with references or personal experience.

To learn more, see our tips on writing great answers.




draft saved


draft discarded














StackExchange.ready(
function ()
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f55369899%2fpowershell-how-to-dynamically-update-a-nested-json-array%23new-answer', 'question_page');

);

Post as a guest















Required, but never shown





















































Required, but never shown














Required, but never shown












Required, but never shown







Required, but never shown

































Required, but never shown














Required, but never shown












Required, but never shown







Required, but never shown







Popular posts from this blog

SQL error code 1064 with creating Laravel foreign keysForeign key constraints: When to use ON UPDATE and ON DELETEDropping column with foreign key Laravel error: General error: 1025 Error on renameLaravel SQL Can't create tableLaravel Migration foreign key errorLaravel php artisan migrate:refresh giving a syntax errorSQLSTATE[42S01]: Base table or view already exists or Base table or view already exists: 1050 Tableerror in migrating laravel file to xampp serverSyntax error or access violation: 1064:syntax to use near 'unsigned not null, modelName varchar(191) not null, title varchar(191) not nLaravel cannot create new table field in mysqlLaravel 5.7:Last migration creates table but is not registered in the migration table

용인 삼성생명 블루밍스 목차 통계 역대 감독 선수단 응원단 경기장 같이 보기 외부 링크 둘러보기 메뉴samsungblueminx.comeh선수 명단용인 삼성생명 블루밍스용인 삼성생명 블루밍스ehsamsungblueminx.comeheheheh

155 수학 과학 기타 둘러보기 메뉴eh추가해eh문서를 완성해