Powershell为什么两个json内容之间有区别? [英] Powershell Why the difference between the two json contents?

查看:54
本文介绍了Powershell为什么两个json内容之间有区别?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有两个Byte[]类型的变量(我为特定需要选择了此类型,因此需要保留.),它们声明为:

I have two variables of Byte[] type (I chose this type for a specific need, so it need to be retained.) which are declared as:

$first = New-Object Byte[] 32
$second = New-Object Byte[] 32

然后,我初始化了两个变量的每个索引.

and, I initalized each index of both the variables.

现在,我创建了一个哈希表$List1:

Now, I created a hashtable $List1 as:

$List1=@{"First" = $first; "Second" = $second}

我正在使用以下语法创建json文件:

I am using the syntax below for creating the json file:

$List1 | ConvertTo-Json | Set-Content  -Path $jsonFile1

这是第一个json文件内容:

This is the first json file content:

{
"First":  {
             "value":  [
                           210,
                           195,
                           131,
                           176,
                           88,
                           154,
                           57,
                           37,
                           2,
                           75,
                           182,
                           190,
                           156,
                           43,
                           113,
                           199,
                           63,
                           25,
                           109,
                           92,
                           220,
                           91,
                           219,
                           252,
                           113,
                           68,
                           202,
                           12,
                           147,
                           194,
                           36,
                           177
                       ],
             "Count":  32
         },
"Second":  {
           "value":  [
                         238,
                         225,
                         12,
                         172,
                         134,
                         94,
                         42,
                         204,
                         27,
                         78,
                         39,
                         166,
                         229,
                         111,
                         143,
                         254
                     ],
           "Count":  16
       }
}

然后我将第一个json文件读入一个临时变量,如下所示:

Then I read the first json file into a temporary variable as below:

$tempHash = Get-Content -Path $jsonFile1 -Raw| ConvertFrom-Json

由于$tempHashPSCustomObject,因此我将创建一个新的哈希表$List2,如下所示:

Since $tempHash is a PSCustomObject, I create a new hashtable $List2 as below:

$List2 = @{"First" = $tempHash.First.value; "Second"= $tempHash.Second.value}

我用来创建第二个json文件,如下所示:

which I use to create the second json file as below:

$List2 | ConvertTo-Json | Set-Content  -Path $jsonFile2

这是第二个json文件内容:

This is the second json file content:

    {
"First":  [
             133,
             231,
             19,
             173,
             60,
             50,
             105,
             68,
             38,
             109,
             99,
             155,
             2,
             188,
             216,
             9,
             8,
             225,
             203,
             15,
             167,
             8,
             188,
             76,
             192,
             154,
             183,
             194,
             1,
             122,
             143,
             137
         ],
"Second":  [
           27,
           3,
           57,
           67,
           155,
           145,
           181,
           194,
           250,
           10,
           65,
           90,
           41,
           230,
           243,
           196
       ]
}

我使用相同的语法来创建两个json文件.那么,为什么它们的结构不同?

I am using the same syntax to create both the json files. So, why are their structures different?

我怀疑,区别在于这种语法:

I suspect, the difference is because of this very syntax:

$List1=@{"First" = $first; "Second" = $second}

因为Byte[]类型变量不能用作简单的integer[]类型变量. 纠正我.

because Byte[] type variable does not work as a simple integer[] type variable. Correct me.

因此,事实证明Byte[]类型变量具有两个不同的键. 值"保存字节值的实际数组,以及 计数"保存Byte[]变量中的元素数. 但是,当我们调用Byte[]类型的变量时,例如:

So, it turns out Byte[] type variable has two different keys. "value" which holds the actual array of byte values, and "Count" which holds the number of elements in the Byte[] variable. However, when we invoke the Byte[] type variable like:

$first

Byte[]类型,我们仅获得值"键下列出的值. "count"键下的值永远不会在控制台中显示,但会以某种方式传递给哈希表.

which is of Byte[] type, we get only the values listed under the "value" key. The value under the "count" key is never displayed in console, yet it is passed to the hashtable somehow.

还有一点要注意.如果我使用:

And, One more point to be noted. If I use:

 $List2 = @{"First" = $tempHash.First; "Second"= $tempHash.Second}

然后,我将不得不使用:

then, I'll have to use:

$List2.First.Value #to get the value of the "First" key

这让我感到不舒服,因为对于$List1哈希表,我只需要使用:

and that makes me feel uncomfortable because for the $List1 hashtable, I only needed to use:

 $List1.First #to get the value of the "First" key.

[解决方法]

我创建了一个hastable $List作为原始哈希表,如下所示,严格仅 一次使用 :

I created a hastable $List as the original hashtable as below for strictly one time use only:

$List | ConvertTo-Json | Set-Content  -Path $jsonFile

然后,我从上面的原始$jsonFile如下创建了两个hastables $List1$List2.

Then, I created two hastables $List1 and $List2 as below from the original $jsonFile above.

 $tempHash = Get-Content -Path $jsonFile -Raw| ConvertFrom-Json
 $List1 = @{"First" = $tempHash.First; "Second" = tempHash.Second}
 $List2 = @{"First" = $tempHash.First; "Second" = tempHash.Second}

当我参考它们的键和值时,这有助于我保持一致.

It helped me keep consistency while referring to their keys and values.

现在,我使用

#to fetch the values of the "First" keys of both hashtables.
$List1.First.value #and
$List2.First.value

类似地,我对哈希表$List1$List2的第二"键也执行相同的操作.

Similarly, I do the same for "Second" key for both hashtables $List1 and $List2.

#to fetch the values of the "Second" keys of both hashtables.
$List1.Second.value #and
$List2.Second.value

事实证明,这是我的Powershell版本中的错误,如下面的@ mklement0所示. 完美的解决方案是改为使用@ mklement0指示的以下语法:

It turned out to be a bug in my version of Powershell as ststed by @mklement0 below. The perfect solution will be to instead use the syntax below as instructed by @mklement0 :

# Ensure that the input array is constructed without the extra [psobject] wrapper.
$First = [Byte[]]::new(32)
$Second = [Byte[]]::new(32)

推荐答案

  • 从v5.1开始,第一次ConvertTo-Json调用的结果是 Windows PowerShell 中的怪胎:生成的JSON应该具有FirstSecond直接包含一个数组 ,而不是具有valueCount属性的 object ,而value包含该数组.

    • The result of the first ConvertTo-Json call is a quirk in Windows PowerShell as of v5.1: the resulting JSON should have First and Second contain an array directly rather than an object with value and Count properties, with value containing the array.

      • 此行为已在PowerShell Core 中已修复;在 Windows PowerShell(从v5.1开始仍然存在)中,它可能会修复,也可能不会修复.
        $a = New-Object Byte[] 2; @{ a = $a } | ConvertTo-Json -Compress产量:
          PowerShell Core v6.0.1中的
        • {"a":[0,0]}-确定.
        • Windows PowerShell v5.1中的
        • {"a":{"value":[0,0],"Count":2}}-损坏.
        • This behavior has been fixed in PowerShell Core; it may or may not get fixed in Windows PowerShell (still present as of v5.1).
          $a = New-Object Byte[] 2; @{ a = $a } | ConvertTo-Json -Compress yields:
          • {"a":[0,0]} in PowerShell Core v6.0.1 - OK.
          • {"a":{"value":[0,0],"Count":2}} in Windows PowerShell v5.1 - BROKEN.

          对于您而言,使用New-Object 会触发该怪癖.

          • 最有可能与此问题有关;请注意,但是,在PowerShell Core中也无法解决上述问题,但是上面链接的修复程序可以解决这种情况下的问题.
          • Most likely it is related to this issue; note, however, that said issue isn't resolved in PowerShell Core either, but the fix linked to above resolves the problems in this context.

          解决方法:

          在脚本/会话开始时,运行:

          At the start of your script/session, run:

          Remove-TypeData System.Array
          

          这将从所有数组对象中删除由ETS提供的过时的.Count属性,这使[psobject]包裹的对象(如New-Object返回的)的问题消失了-有关说明,请参见我的答案.

          This removes the obsolete ETS-supplied .Count property from all array objects, which makes the problem go away for [psobject]-wrapped objects (such as returned by New-Object) - for an explanation, see this answer of mine.

          更多繁琐的解决方法:

          如果您确保-is [psobject]不再对输入数组报告为真,问题就消失了,这可以通过以下方式之一完成:

          The problem goes away if you ensure that -is [psobject] no longer reports true for the input arrays, which can be done in one of the following ways:

          • [PSv5 +]:$First = [Byte[]]::new(32)-使用表达式而不是命令可以使问题消失,因为它不会创建额外的,不可见的[psobject]包装器.

          • [PSv5+]: $First = [Byte[]]::new(32) - use of an expression rather than a command makes the problem go away, because it doesn't create an extra, invisible [psobject] wrapper.

          [PSv4-]:$First = (New-Object Byte[] 32).psobject.BaseObject-显式绕过多余的[psobject]包装器可以解决问题.

          [PSv4-]: $First = (New-Object Byte[] 32).psobject.BaseObject - explicitly bypassing the extra [psobject] wrapper makes the problem go away.

          简化的示例(PSv5 +,但很容易适应较早的版本;省略了文件操作,因为它们是问题的附带内容)

          Simplified example (PSv5+, but easily adapted to earlier versions; file operations omitted, because they are incidental to the problem):

          # Ensure that the input array is constructed without the extra [psobject] wrapper.
          $First = [Byte[]]::new(2)
          
          # Construct a hashtable...
          $List1 = @{ First = $first }
          # ... and convert it to JSON:
          ($json = $List1 | ConvertTo-Json)
          

          上面的代码现在可以正确产生(具有valuecount属性的 no 无关对象):

          The above now correctly yields (no extraneous object with value and count properties):

          {
              "First":  [
                            0,
                            0
                        ]
          }
          

          现在可以将此JSON字符串转换为对象了:

          Reconverting this JSON string to an object now works as expected:

          # Re-convert: $tempObj.First then *directly* contains the input array
          #             (there is no .Value property anymore).
          $tempObj = $json | ConvertFrom-Json
          
          # Construct a new hashtable...
          $List2 = @{ First = $tempObj.First }
          # ... and convert it to JSON.
          $List2 | ConvertTo-Json
          

          结果是与上面相同的JSON字符串.

          The result is the same JSON string as above.

          这篇关于Powershell为什么两个json内容之间有区别?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆