PowerShell的 - 访问一个JArray一个JObject

问题描述:

我有一个JSON对象PowerShell的 - 访问一个JArray一个JObject

{ 
    "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" 
     } 
    ] 
} 

,我通过

$config = [Newtonsoft.Json.Linq.JObject]::Parse($file) 

创建我可以访问之类的东西

$config["ProjectDirectory"] 
$config["VirtualDirectories"] 

但我可以在里面没有得到VirtualDirectories里面的元素JArray

我证实

$config["VirtualDirectories"][0].GetType() // JObject 
$config["VirtualDirectories"].GetType() // JArray 
$config // JObject 

我已经试过

$config["VirtualDirectories"][0]["Name"] 
$config["VirtualDirectories"][0]["Path"] 
$config["VirtualDirectories"][0][0] 
$config["VirtualDirectories"][0].GetValue("Name") 

当我尝试

$config["VirtualDirectories"][0].ToString() 

我得到

{ 
     "Name": "Alerts", 
     "Path": "\\Areas\\RemoteOrder\\Views\\Alerts" 
} 

什么我真的想做的是访问它一个循环,但我可以再次似乎没有访问JObject元素

你就近了。 $config["VirtualDirectories"][0]["Name"]会给你一个JValue包含文字。您只需使用Value属性即可获取实际的字符串。这里是你将如何做一个ForEach循环:

$config = [Newtonsoft.Json.Linq.JObject]::Parse($file) 

ForEach ($dir in $config["VirtualDirectories"]) 
{ 
    $name = $dir["Name"].Value 
    $path = $dir["Path"].Value 
    ... 
} 

补充Brian Rogers' helpful answer

作为一个更方便的替代指数语法(["<name>"]),可以使用财产语法
.<name>),因为返回的JObject实例具有动态属性,它们的键名为:

$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', ... 
} 

我推测的理由您选择工作,Json.NET类型直接性能相比PowerShell的内置ConvertFrom-Json cmdlet的。

  • 顺便说一句:有一个PowerShell wrapper for Json.NET您可以用Install-Module -Scope CurrentUser newtonsoft.json安装,例如,它隐,您可以访问到[Newtonsoft.Json.Linq.JObject]类型。然而,这个包装 - 它表示对象订购散列表 - 是甚至比ConvertFrom-Json慢。

  • 除了性能,以下限制ConvertFrom-Json可能会使有必要使用第三方库,如Json。无论如何:

    • 不支持空字符串键。
    • 不支持在情况下(例如,fooFoo)不同的密钥。

为了便于比较,这里的相当于 - 但一般速度较慢 - ConvertFrom-Json解决方案

ConvertFrom-Json表示JSON对象作为[pscustomobject]情况下,其属性命名为键,允许更自然的语法而不需要访问.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', ... 
}