我在用powershell读取JSON文件,替换值并写回该文件或文件时遇到了困难。
给出以下内容:
[Object]$QuickJson = @'
{
"swagger": "1.0",
"info": {
"version": "0.0.1",
"title": "this is a title",
"description": "this is a description"
},
"basePath": "/test",
"paths" : {
"/GetSomething": {
"get": {
"name" : "test01"
}
},
"/GetSomethingElse" : {
"get": {
"name" : "test02"
}
},
"/GetAnotherThing": {
"get": {
"name" : "test03"
}
}
}
}
'@
我在这里感兴趣的是用其他东西替换“ paths”对象中的值。我读取了文件,但是可以通过尝试的操作访问该对象:
[object]$MyPSJson = ConvertFrom-Json -InputObject $QuickJson
foreach($info in $MyPSJson.paths.PSObject.Properties)
{
$path = $info.Name
Write-Host "path: $path"
$info.Name = "$path?code=fsfsfsfsfsfdfds"
Write-Host $info.Name
}
我不知道这些“路径”将是什么,我需要采用现有值并向其附加代码值,因此我需要能够遍历所有路径并进行此替换。当我尝试上面的时候,我得到一个错误:
路径:/ GetSomething -'名称'是ReadOnly属性。在C:\ scripts \ test.ps1:44 char:5 + $ info.Name =“ $ path?code = fsfsfsfsfsfdfds” + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + CategoryInfo:InvalidOperation:(:) [],RuntimeException + FullyQualifiedErrorId:PropertyAssignmentException
我尝试了几种不同的方法,但仍未提出好的或可行的解决方案。任何帮助或指向正确的方向,我们将不胜感激。
答案 0 :(得分:2)
您可以执行与现在非常相似的操作,只是无需更改记录初始属性的现有属性,而是添加具有所需修改的新属性,然后将$MyPSJson.paths
设置为自身(不包括旧属性) ,所以所有这些都是新属性。
#Find initial paths
$Paths=$MyPSJson.paths.psobject.Properties.Name
#Add new paths with the modification to the name, and set the value to the same as the old path
$Paths|%{Add-Member -InputObject $MyPSJson.paths -NotePropertyName "$_`?code=fsfsfsfsfsfdfds" -NotePropertyValue $MyPSJson.paths.$_}
#Set the paths object to itself, excluding the original paths
$MyPSJson.paths = $MyPSJson.paths|Select * -ExcludeProperty $Paths
答案 1 :(得分:1)
尝试以下(PSv3 +):
$MyPSJson.paths = $MyPSJson.paths.psobject.properties |
ForEach-Object { $renamedProps = [ordered] @{} } {
$renamedProps[$_.Name + '?foo=bar&baz=bam'] = $_.Value
} { [pscustomobject] $renamedProps }
从技术上讲,此使用修改后的属性名称重新创建.paths
对象。
通过枚举原始属性,将它们的修改后名称下的值添加到有序哈希表中来完成,该哈希表在管道完成后会转换为自定义对象([pscustomobject]
)。
关于您尝试过的事情:
给定对象的属性不能重命名-只能更改其属性的值。
因此,必须使用所需的新属性名称和与原始属性相同的值创建一个 new 对象。
顺便说一句:[object]
强制转换在PowerShell中是没有意义的-它是有效的禁止操作。
相比之下,[pscustomobject]
强制转换可用于从[有序]哈希表中创建[pscustomobject]
实例,这是上面使用的技术;从其他类型进行的投射又是虚拟的无操作。
答案 2 :(得分:0)
除了对我有用的公认答案外,我还发现了最初建议的另一种使用哈希表的方法:
function Convert-JsonFileToHashTable([string]$file) {
$text = [IO.File]::ReadAllText($file)
$parser = New-Object Web.Script.Serialization.JavaScriptSerializer
$parser.MaxJsonLength = $text.length
$hashtable = $parser.Deserialize($text, @{}.GetType())
return $hashtable
}
$hashtable = Convert-JsonFileToHashTable (Resolve-Path -Path $DefinitionFile)
$keys = New-Object System.Collections.ArrayList($null)
$keys.AddRange($hashtable["paths"].Keys)
foreach ($key in $keys)
{
$newPath = $key + "?code=$Code"
$hashtable["paths"].$newPath = $hashtable["paths"].$key
$hashtable["paths"].Remove($key) | Out-Null
}
$json = $hashtable | ConvertTo-Json -Depth 20
Write-Output $json | Out-File $newFile -Encoding utf8