json - 设置从包含注释的 json 加载的对象的属性值

标签 json powershell powershell-7.0

当从 json 文件加载对象时,通常可以设置属性值并将文件写回,如下所示:

$manifest = (gc $manifestPath) | ConvertFrom-Json -AsHashtable
$manifest.name = "$($manifest.name)-sxs"
$manifest | ConvertTo-Json -depth 100 | Out-File $manifestPath -Encoding utf8NoBOM

但是如果源json文件包含注释,则无法设置对象的属性:

// *******************************************************
// GENERATED FILE - DO NOT EDIT DIRECTLY
// *******************************************************
{
  "name": "PublishBuildArtifacts"
}

运行上面的代码会引发错误:

$manifest

id                 : 1D341BB0-2106-458C-8422-D00BCEA6512A
name               : PublishBuildArtifacts
friendlyName       : ms-resource:loc.friendlyName
description        : ms-resource:loc.description
category           : Build
visibility         : {Build}
author             : Microsoft Corporation
version            : @{Major=0; Minor=1; Patch=71}
demands            : {}
inputs             : {@{name=CopyRoot; type=filePath; label=ms-resource:loc.input.label.CopyRoot; defaultValue=;
                     required=False; helpMarkDown=Root folder to apply copy patterns to.  Empty is the root of the
                     repo.}, @{name=Contents; type=multiLine; label=ms-resource:loc.input.label.Contents;
                     defaultValue=; required=True; helpMarkDown=File or folder paths to include as part of the
                     artifact.}, @{name=ArtifactName; type=string; label=ms-resource:loc.input.label.ArtifactName;
                     defaultValue=; required=True; helpMarkDown=The name of the artifact to create.},
                     @{name=ArtifactType; type=pickList; label=ms-resource:loc.input.label.ArtifactType;
                     defaultValue=; required=True; helpMarkDown=The name of the artifact to create.; options=}…}
instanceNameFormat : Publish Artifact: $(ArtifactName)
execution          : @{PowerShell=; Node=}

$manifest.name
PublishBuildArtifacts

$manifest.name = "sxs"
InvalidOperation: The property 'name' cannot be found on this object. Verify that the property exists and can be set.

当我删除注释时,我可以覆盖该属性。

有没有办法让PowerShell在加载json文件/转换对象并生成可写对象时忽略注释?

最佳答案

我不确定这是否是有意为之,但看起来像 ConvertFrom-Json将 Json 上的注释视为 $null当将其转换为对象时。 只有在收到 object[] 时才会发生这种情况来自管道,使用字符串多行字符串可以正常工作

使用问题中发布的完全相同的 Json 来演示这一点的简单方法:

$contentAsArray = Get-Content test.json | Where-Object {
    -not $_.StartsWith('/')
} | ConvertFrom-Json -AsHashtable

$contentAsArray['name'] = 'hello' # works

在这里您可以看到差异和解决方法,绝对推荐使用 -RawGet-Content所以您将多行字符串传递给 ConvertFrom-Json :

$contentAsString = Get-Content test.json -Raw | ConvertFrom-Json -AsHashtable
$contentAsArray = Get-Content test.json | ConvertFrom-Json -AsHashtable

$contentAsString.PSObject, $contentAsArray.PSObject | Select-Object TypeNames, BaseObject

TypeNames                                      BaseObject
---------                                      ----------
{System.Collections.Hashtable, System.Object}  {name}
{System.Object[], System.Array, System.Object} {$null, System.Collections.Hashtable}


$contentAsArray['name']      # null
$null -eq $contentAsArray[0] # True
$contentAsArray[1]['name']   # PublishBuildArtifacts
$contentAsArray[1]['name'] = 'hello'
$contentAsArray[1]['name']   # hello

关于json - 设置从包含注释的 json 加载的对象的属性值,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/71025659/

相关文章:

json - MongoDB,find() 结果,转换为 json

javascript - 是时候在客户端启动一个计数器了

powershell - 使用 "dot"变量名称的数组设置 PSObject 路径

适用于 PowerShell 7 的 Azure 自动化混合工作人员 Get-AutomationPSCredential

powershell - Linux PowerShell 中的 'nohup' 是什么?

android - 如何使用 Retrofit 2 从 JSON 列表中获取 List<String>?

ios - UITableView 未使用 NSArray 内容正确填充部分

powershell - powershell 对象中的十六进制格式

powershell - 远程范围到本地

powershell - 将内容插入Powershell中的文本文件