I have a Json object
{
"ProjectDirectory": "C:\\Main",
"SiteName": "RemoteOrder",
"ParentPath": "/Areas//Views",
"VirtualDirectories": [
{
"Name": "Alerts",
"Path": "\\Areas\\RemoteOrder\\Views\\Alerts"
},
{
"Name": "Analytics",
"Path": "\\Areas\\RemoteOrder\\Views\\Analytics"
},
{
"Name": "Auth",
"Path": "\\Areas\\RemoteOrder\\Views\\Auth"
}
]
}
that I created by
$config = [Newtonsoft.Json.Linq.JObject]::Parse($file)
I can access things like
$config["ProjectDirectory"]
$config["VirtualDirectories"]
But I can not get to the element inside the VirtualDirectories JArray
I confirmed
$config["VirtualDirectories"][0].GetType() // JObject
$config["VirtualDirectories"].GetType() // JArray
$config // JObject
I have tried
$config["VirtualDirectories"][0]["Name"]
$config["VirtualDirectories"][0]["Path"]
$config["VirtualDirectories"][0][0]
$config["VirtualDirectories"][0].GetValue("Name")
When I try
$config["VirtualDirectories"][0].ToString()
I get
{
"Name": "Alerts",
"Path": "\\Areas\\RemoteOrder\\Views\\Alerts"
}
What I am really trying to do is access it a loop but again I can not seem to access the JObject Elements
You are close. $config["VirtualDirectories"][0]["Name"]
will give you a JValue
containing the text. You just need to use the Value
property from there to get the actual string. Here is how you would do it in a ForEach
loop:
$config = [Newtonsoft.Json.Linq.JObject]::Parse($file)
ForEach ($dir in $config["VirtualDirectories"])
{
$name = $dir["Name"].Value
$path = $dir["Path"].Value
...
}
To complement Brian Rogers' helpful answer:
As a more convenient alternative to index syntax (["<name>"]
) you can use property syntax
(.<name>
), because the JObject
instances returned have dynamic properties named for their keys:
$config = [Newtonsoft.Json.Linq.JObject]::Parse($file)
foreach ($dir in $config.VirtualDirectories) {
$name = $dir.Name.Value # as in Brian's answer: note the need for .Value
$path = $dir.Path.Value # ditto
# Sample output
"$name=$path" # outputs 'Alerts=\Areas\RemoteOrder\Views\Alerts', ...
}
I presume that the reason you chose to work with Json.NET types directly is performance compared to PowerShell's built-in ConvertFrom-Json
cmdlet.
As an aside: There is a PowerShell wrapper for Json.NET that you can install with Install-Module -Scope CurrentUser newtonsoft.json
, for instance, which implicitly gives you access to the [Newtonsoft.Json.Linq.JObject]
type. However, this wrapper - which represents objects as ordered hashtables - is even slower than ConvertFrom-Json
.
Aside from performance, the following limitations of ConvertFrom-Json
may make it necessary to use a third-party library such as Json.Net anyway:
foo
vs. Foo
) are not supported.For contrast, here's the equivalent - but generally slower - ConvertFrom-Json
solution:
ConvertFrom-Json
represents the JSON objects as [pscustomobject]
instances whose properties are named for the keys, allowing for a more natural syntax without the need to access .Value
:
$config = ConvertFrom-Json $json
foreach ($dir in $config.VirtualDirectories) {
$name = $dir.Name # no .Value needed
$path = $dir.Path # ditto
# Sample output
"$name=$path" # outputs 'Alerts=\Areas\RemoteOrder\Views\Alerts', ...
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With