Как заменить свойство в файле JSON в PowerShell - PullRequest
0 голосов
/ 11 октября 2018

Мне трудно читать в файле JSON в powershell, заменить значение и записать обратно в файл или файл.

Учитывая следующее:

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

Я не знаю, какими будут эти "пути", мне нужно взять существующее значение и добавить кодзначение для этого, поэтому мне нужно иметь возможность перебрать все пути и сделать эту замену.Когда я пытаюсь выполнить вышеизложенное, я получаю сообщение об ошибке:

path: / GetSomething - 'Name' является свойством ReadOnly.В C: \ scripts \ test.ps1: 44 char: 5 + $ info.Name = "$ path? Code = fsfsfsfsfsfdfds" + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + CategoryInfo: InvalidOperation: (:) [], RuntimeException + FullyQualifiedErrorId: PropertyAssignmentException

Я пробовал несколькоразные вещи и еще предстоит придумать хорошее или работоспособное в этом отношении решение.Любая помощь или указание в правильном направлении очень ценится.

Ответы [ 3 ]

0 голосов
/ 12 октября 2018

Попробуйте следующее (PSv3 +):

$MyPSJson.paths = $MyPSJson.paths.psobject.properties |
  ForEach-Object { $renamedProps = [ordered] @{} } { 
    $renamedProps[$_.Name + '?foo=bar&baz=bam'] = $_.Value
  } { [pscustomobject] $renamedProps }

С технической точки зрения этот воссоздает .paths объект с измененными именами свойств.

Это такперечисляя исходные свойства, добавляя их значения под измененным именем в упорядоченную хеш-таблицу, которая по завершении конвейера преобразуется в пользовательский объект ([pscustomobject]).


Как и для то, что вы пробовали :

Свойства данного объекта не могут быть переименованы - только его свойства ' значения могут быть изменены.

Следовательно,Вы должны создать новый объект с желаемыми новыми именами свойств и такими же значениями, что и у оригинала.

В качестве отступления: приведение [object] бессмысленно в PowerShell - оно эффективноno-op.
В отличие от этого, [pscustomobject] приведение может использоваться для создания [pscustomobject] экземпляров из [упорядоченных] хеш-таблиц , что является техникой, использованной выше;приведение из других типов снова является виртуальным запретом.

0 голосов
/ 12 октября 2018

В дополнение к принятому ответу, который работал для меня, я также нашел другой способ, который был первоначально предложен, который должен был использовать хеш-таблицу:

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
0 голосов
/ 12 октября 2018

Вы можете сделать что-то очень похожее на то, что у вас есть сейчас, просто вместо того, чтобы изменять существующие свойства, вы записываете начальные свойства, добавляете новые с нужными вам модификациями, а затем устанавливаете $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
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...