【问题标题】:ConvertFrom-Json : Cannot convert the JSON string because a dictionary that was converted from the string contains the duplicated keysConvertFrom-Json :无法转换 JSON 字符串,因为从字符串转换的字典包含重复的键
【发布时间】:2014-02-27 21:05:02
【问题描述】:

从 OData API 服务返回以下 JSON:

{
  "d": {
    "results": [
      {
        "FileSystemObjectType": 0,
        "Id": 1,
        "ContentTypeId": "0x0100BC97B2F575CB0C42B79549F3BABD32A8",
        "Title": "Nokia California",
        "Address": "200 South Matilda Avenue\nW Washington Ave\n94086 Sunnyvale, California\nUnited States of America",
        "ID": 1,
        "Modified": "2014-02-24T10:06:39Z",
        "Created": "2014-02-24T10:06:39Z",
        "AuthorId": 12,
        "EditorId": 12,
        "OData__UIVersionString": "1.0",
        "Attachments": false,
        "GUID": "d12aafad-502a-4968-a69e-36a7ea05ec80"
      }
    ]
  }
}

并作为字符串保存到名为$data的变量中

尝试使用ConvertFrom-Json cmdlet 将 JSON 格式的字符串转换为自定义对象:

$results = $data | ConvertFrom-Json

给出以下错误:

ConvertFrom-Json : 无法转换 JSON 字符串,因为字典 从字符串转换的包含重复键“Id” 和“身份证”。

有没有办法在PowerShell中转换指定的JSON格式的字符串?

【问题讨论】:

    标签: json rest powershell


    【解决方案1】:

    这就是我的做法:

    $results = $data.ToString().Replace("ID", "_ID") | ConvertFrom-Json
    

    【讨论】:

    • 我更喜欢这个,但我会推荐这个小修改: $results = $data.ToString().Replace("""ID""", "_ID") | ConvertFrom-Json 将仅针对“ID”(如果它是整个属性名称,它将出现在属性名称中)但避免修改选择的任何其他属性,其中“ID”仅作为名称的一部分出现。例如,避免将“FLUID_VOLUME”更改为“FLU_ID_VOLUME”。
    【解决方案2】:

    在 PowerShell V1.0 中,或者在 PowerShell V2.0 中 JSON 太大时,我仍然使用到 XML 的转换:

    Add-Type -AssemblyName System.ServiceModel.Web, System.Runtime.Serialization
    function Convert-JsonToXml
    {
      PARAM([Parameter(ValueFromPipeline=$true)][string[]]$json)
    
      BEGIN
      { 
        $mStream = New-Object System.IO.MemoryStream 
      }
    
      PROCESS
      {
        $json | Write-String -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()
        }
      }
    }
    

    使用此代码,您可以遍历您可以测试的项目:

    $a = Get-Content C:\temp\jsontest.txt
    $b.root.d.results.Item
    $b.root.d.results.Item[7].Id[0].InnerText
    

    (已编辑)

    在你的情况下,我只会替换预期的重复 ID/Id

    $data = Get-Content C:\temp\jsontest.txt -Raw
    $datacorrected = $a -creplace '"Id":','"Id-minus":'
    $psJsonIn = $datacorrected | ConvertFrom-Json
    

    如果你真的有意外的重复,你可以编写一个函数来捕获由于重复键导致的转换错误并替换一个。

    【讨论】:

    • 谢谢!那么,您是在建议我将 JSON 格式的字符串转换为 Xml,对吗?但我想坚持使用 JSON,也许有可能以某种方式过滤 json 字符串以排除重复的键(在我的情况下为 ID,id)?
    • @Vadim Gremyachev,我编辑了我的答案,转了一圈(不是更好)。
    【解决方案3】:

    ConvertFrom-JSON 它将尝试从 JSON 字符串创建一个 PS 自定义对象。 PowerShell 对象属性名称不区分大小写,因此“ID”和“id”表示相同的属性名称。在尝试进行该转换之前,您必须对 JSON 中的那些重复属性名称进行处理,否则它将失败。

    【讨论】:

      猜你喜欢
      • 2014-07-06
      • 2019-09-19
      • 2017-02-03
      • 2018-10-16
      • 2016-04-10
      • 2019-05-11
      • 1970-01-01
      • 1970-01-01
      • 2021-11-04
      相关资源
      最近更新 更多