【问题标题】:How do I use Json.NET to parse json in PowerShell?如何使用 Json.NET 在 PowerShell 中解析 json?
【发布时间】:2012-12-07 17:27:08
【问题描述】:

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

我有这个 JSON:

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

我使用以下代码加载 JSON.NET 程序集:

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

并尝试用

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

现在我希望 $result["Name"]Apple 但我什么也得不到。有什么想法吗?

代码´$result.ContainsKey("Name")returnsTruebut$result.GetValue("Name")returnsnull`。

【问题讨论】:

    标签: json powershell json.net


    【解决方案1】:

    好的,这就是我的做法,因此它至少可以在 Windows 2008 上运行到 PowerShell v2。

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

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

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

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

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

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

    如果你有很多事情,你需要做类似的事情

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

    访问您编写的嵌套项目

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

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

    【讨论】:

    • 您还可以使用数组语法获取嵌套值。 $config["SomeItem"]["NestedItem"].ToString()
    【解决方案2】:

    如果您在这里使用 Powershell 5.0,可以通过powershell gallery 获得它

    Install-Module Newtonsoft.Json
    Import-Module Newtonsoft.Json
    
    $json = '{"test":1}'
    [Newtonsoft.Json.Linq.JObject]::Parse($json)
    

    【讨论】:

    • 小心这个 - 它不是官方版本,它包含的 Json.net 版本可以追溯到 2018 年 10 月
    【解决方案3】:

    也许这就是你所追求的:

    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
    

    输出:

    <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>
    

    如果你想要名称节点:

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

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

    【讨论】:

    • 什么太复杂了??我已经编辑了我的答案并提供了一个例子。顺便说一句,我不认为 $json 是一个有效的 json (检查jsonlint.com)
    • 您对 json 不正确是正确的,我已经对其进行了更新并删除了使其正确的日期部分。但是,我确实喜欢您的回答,因此您对此投了赞成票,但出于两个原因,它没有回答我的问题。 1. 我问过如何用 Json.NET 来做。 2.我不想将json解析为xml,我希望它被解析。我用 Json.Net 找到了一个我正在尝试的解决方案,它非常简单,很快就会作为答案发布。
    • 查看我的回答,了解我是如何做到的。
    • 我会的,但我得先等20个小时。
    • 不是想欺骗任何人,只是想解释为什么我认为它也太复杂了。从字符串反序列化到 xml,然后再到 json,会为复杂对象或复杂值打开许多可能的错误(因为我们正在跨语言“翻译”,几乎当你从英语翻译成西班牙语然后再翻译成法语时。你会失去上下文和内容)。
    猜你喜欢
    • 2010-09-28
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-03-05
    • 2014-11-19
    • 1970-01-01
    • 2012-11-08
    • 1970-01-01
    相关资源
    最近更新 更多