如何使用Json.NET在PowerShell中解析json?

时间:2022-12-28 07:14:58

I want to parse JSON in PowerShell but I can't use the new v3 functions that are available in PowerShell. My first thought was to load the JSON.Net assembly and use that to parse the JSON string but it doesn't work as I expect it to.

我想在PowerShell中解析JSON但我不能使用PowerShell中提供的新v3函数。我的第一个想法是加载JSON.Net程序集并使用它来解析JSON字符串,但它不能像我期望的那样工作。

I have this JSON:

我有这个JSON:

$json = "{""Name"": ""Apple"",  
           ""Price"": 3.99,  
            ""Sizes"": [    
                 ""Small"",    
                 ""Medium"",
                 ""Large""]}"

I load the JSON.NET assembly with this code:

我用这段代码加载JSON.NET程序集:

[Reflection.Assembly]::LoadFile("$currentPath\Newtonsoft.Json.dll”)

And tries to parse it with

并尝试解析它

$result = [Newtonsoft.Json.JsonConvert]::DeserializeObject($json)

Now I expect that $result["Name"] is Apple but I get nothing there. Any ideas?

现在我希望$ result [“Name”]是Apple,但我什么都没得到。有任何想法吗?

The code ´$result.ContainsKey("Name")returnsTruebut$result.GetValue("Name")returnsnull`.

代码'$ result.ContainsKey(“Name”)returnTrue但$ result.GetValue(“Name”)returnsnull`。

2 个解决方案

#1


10  

Ok, so here is how I did it so it works down to at least PowerShell v2 on Windows 2008.

好的,所以这就是我如何做到这一点所以它至少适用于Windows 2008上的PowerShell v2。

First, load the Json.NET assembly for the version you would like to use, I took the .NET 3.5 version:

首先,为您想要使用的版本加载Json.NET程序集,我使用了.NET 3.5版本:

[Reflection.Assembly]::LoadFile("Newtonsoft.Json.dll")

I had the JSON in a file since it was used in a deployment configuration I wrote, so I needed to read the file and then parse the json

我在文件中使用了JSON,因为它在我编写的部署配置中使用,所以我需要读取文件然后解析json

$json = (Get-Content $FileName | Out-String) # read file
$config = [Newtonsoft.Json.Linq.JObject]::Parse($json) # parse string

Now to get values from the config you need to to use the Item method which seems defined by PowerShell on hashtables/dictionaries. So to get an item that is a simple string you would write:

现在要从配置中获取值,您需要使用似乎由PowerShell在哈希表/字典上定义的Item方法。因此,要获得一个简单字符串的项目,您可以编写:

Write-Host $config.Item("SomeStringKeyInJson").ToString()

If you had an array of things you would need to do something like

如果你有一系列的东西,你需要做一些事情

$config.Item("SomeKeyToAnArray") | ForEach-Object { Write-Host $_.Item("SomeKeyInArrayItem").ToString() }

To access nested items you write

要访问您编写的嵌套项

$config.Item("SomeItem").Item("NestedItem")

That's how I solved parsing JSON with Json.NET in PowerShell.

这就是我在PowerShell中用Json.NET解析JSON的方法。

#2


5  

maybe this is what you're after :

也许这就是你所追求的:

http://poshcode.org/2930

http://poshcode.org/2930

    function Convert-JsonToXml {
PARAM([Parameter(ValueFromPipeline=$true)][string[]]$json)
BEGIN { 
   $mStream = New-Object System.IO.MemoryStream 
}
PROCESS {
   $json | Write-Stream -Stream $mStream
}
END {
   $mStream.Position = 0
   try
   {
      $jsonReader = [System.Runtime.Serialization.Json.JsonReaderWriterFactory]::CreateJsonReader($mStream,[System.Xml.XmlDictionaryReaderQuotas]::Max)
      $xml = New-Object Xml.XmlDocument
      $xml.Load($jsonReader)
      $xml
   }
   finally
   {
      $jsonReader.Close()
      $mStream.Dispose()
   }
}
}

function Write-Stream {
PARAM(
   [Parameter(Position=0)]$stream,
   [Parameter(ValueFromPipeline=$true)]$string
)
PROCESS {
  $bytes = $utf8.GetBytes($string)
  $stream.Write( $bytes, 0, $bytes.Length )
}  
}



$json = '{
    "Name": "Apple",
    "Expiry": 1230422400000,
    "Price": 3.99,
    "Sizes": [
        "Small",
        "Medium",
        "Large"
    ]
}'

Add-Type -AssemblyName System.ServiceModel.Web, System.Runtime.Serialization
$utf8 = [System.Text.Encoding]::UTF8                 
(convert-jsonToXml $json).innerXML

Output :

输出:

<root type="object"><Name type="string">Apple</Name><Expiry type="number">1230422
400000</Expiry><Price type="number">3.99</Price><Sizes type="array"><item type="s
tring">Small</item><item type="string">Medium</item><item type="string">Large</it
em></Sizes></root>

If you want the name node :

如果您想要名称节点:

$j=(convert-jsonToXml $json)
$j.SelectNodes("/root/Name")

or

要么

$j |Select-Xml -XPath "/root/Name" |select -ExpandProperty node

#1


10  

Ok, so here is how I did it so it works down to at least PowerShell v2 on Windows 2008.

好的,所以这就是我如何做到这一点所以它至少适用于Windows 2008上的PowerShell v2。

First, load the Json.NET assembly for the version you would like to use, I took the .NET 3.5 version:

首先,为您想要使用的版本加载Json.NET程序集,我使用了.NET 3.5版本:

[Reflection.Assembly]::LoadFile("Newtonsoft.Json.dll")

I had the JSON in a file since it was used in a deployment configuration I wrote, so I needed to read the file and then parse the json

我在文件中使用了JSON,因为它在我编写的部署配置中使用,所以我需要读取文件然后解析json

$json = (Get-Content $FileName | Out-String) # read file
$config = [Newtonsoft.Json.Linq.JObject]::Parse($json) # parse string

Now to get values from the config you need to to use the Item method which seems defined by PowerShell on hashtables/dictionaries. So to get an item that is a simple string you would write:

现在要从配置中获取值,您需要使用似乎由PowerShell在哈希表/字典上定义的Item方法。因此,要获得一个简单字符串的项目,您可以编写:

Write-Host $config.Item("SomeStringKeyInJson").ToString()

If you had an array of things you would need to do something like

如果你有一系列的东西,你需要做一些事情

$config.Item("SomeKeyToAnArray") | ForEach-Object { Write-Host $_.Item("SomeKeyInArrayItem").ToString() }

To access nested items you write

要访问您编写的嵌套项

$config.Item("SomeItem").Item("NestedItem")

That's how I solved parsing JSON with Json.NET in PowerShell.

这就是我在PowerShell中用Json.NET解析JSON的方法。

#2


5  

maybe this is what you're after :

也许这就是你所追求的:

http://poshcode.org/2930

http://poshcode.org/2930

    function Convert-JsonToXml {
PARAM([Parameter(ValueFromPipeline=$true)][string[]]$json)
BEGIN { 
   $mStream = New-Object System.IO.MemoryStream 
}
PROCESS {
   $json | Write-Stream -Stream $mStream
}
END {
   $mStream.Position = 0
   try
   {
      $jsonReader = [System.Runtime.Serialization.Json.JsonReaderWriterFactory]::CreateJsonReader($mStream,[System.Xml.XmlDictionaryReaderQuotas]::Max)
      $xml = New-Object Xml.XmlDocument
      $xml.Load($jsonReader)
      $xml
   }
   finally
   {
      $jsonReader.Close()
      $mStream.Dispose()
   }
}
}

function Write-Stream {
PARAM(
   [Parameter(Position=0)]$stream,
   [Parameter(ValueFromPipeline=$true)]$string
)
PROCESS {
  $bytes = $utf8.GetBytes($string)
  $stream.Write( $bytes, 0, $bytes.Length )
}  
}



$json = '{
    "Name": "Apple",
    "Expiry": 1230422400000,
    "Price": 3.99,
    "Sizes": [
        "Small",
        "Medium",
        "Large"
    ]
}'

Add-Type -AssemblyName System.ServiceModel.Web, System.Runtime.Serialization
$utf8 = [System.Text.Encoding]::UTF8                 
(convert-jsonToXml $json).innerXML

Output :

输出:

<root type="object"><Name type="string">Apple</Name><Expiry type="number">1230422
400000</Expiry><Price type="number">3.99</Price><Sizes type="array"><item type="s
tring">Small</item><item type="string">Medium</item><item type="string">Large</it
em></Sizes></root>

If you want the name node :

如果您想要名称节点:

$j=(convert-jsonToXml $json)
$j.SelectNodes("/root/Name")

or

要么

$j |Select-Xml -XPath "/root/Name" |select -ExpandProperty node