0

我需要与期望对象数组以及其他参数的 API 进行交互。例子:

{
    "fields":  {
        "somefield": "somevalue",
        "someobject": {
            "name": "foobar"
        },
        "versions":  [
            {
                "name": "1.0"
            }
        ]
    }
}

在这个答案的帮助下,我尝试了两种不同的处理方式。我将它们组合成一个代码示例:

$versionName = New-Object -TypeName PSObject
$versionName | Add-Member -Name "name" -MemberType NoteProperty -Value "1.0"

$versionName2 = @{}
$versionName2.name = "1.0"

$postIssueBody = @{}
$postIssueBody.fields = @{}
$postIssueBody.fields.somefield = "somevalue"
$postIssueBody.fields.someobject = @{}
$postIssueBody.fields.someobject.name = "foobar"
$postIssueBody.fields.version = @($versionName)
$postIssueBody.fields.version2 = @()
$postIssueBody.fields.version2 += [pscustomobject]$versionName2

$postIssueRequestJson = $postIssueBody | ConvertTo-Json

$postIssueRequestJson

这将产生以下输出:

{
    "fields":  {
        "somefield": "somevalue",
        "someobject": {
            "name": "foobar"
        },
        "version":  [
            "@{name=1.0}"
        ],
        "version2":  [
            "@{name=1.0}"
        ]
    }
}

如您所见,这不会像有效的 JSON 那样有效。处理此分配的最佳方法是什么,以便在通过后正确形成版本名称ConvertTo-Json

4

2 回答 2

2

ConvertTo-Json函数有一个名为 的开关Depth。它通知 Convert 函数在将数据转换为 JSON 格式时应该走多深。默认情况下,它设置为 2。由于未正确转换的数据位于深度 3,我们只需将深度设置为该深度,如下所示:

$postIssueRequestJson = $postIssueBody | ConvertTo-Json -Depth 3

现在我们有了格式良好的 JSON。

{
    "fields":  {
        "somefields":  "somevalue",
        "someobject":  {
            "name":  "foobar"
        },
        "versions":  [
            {
                "name":  "1.0"
            }
        ]
    }
}
于 2014-08-16T02:33:49.020 回答
-1

好的,我想我明白了。因此,您需要一个以对象数组开头"versions":并后跟对象数组的字符串,是吗?所以,让我们从一个空数组开始。

$Array = @()

然后我们可以创建对象,并将它们添加到数组中:

$Array += [PSCustomObject]@{"Name1"="1.0.0"}
$Array += [PSCustomObject]@{"Name2"="3.10.0"}

现在我们有了一个包含 PSCustomObjects 的 PowerShell 数组。我们可以将它通过管道传递给 ConvertTo-JSON,它会输出:

[
    {
        "Name1":  "1.0.0"
    },
    {
        "Name2":  "3.10.0"
    }
]

这是您想要的对象数组。如果您希望一个对象具有它的价值,您可以简单地创建另一个对象来做到这一点:

$Versions = [PSCustomObject]@{'versions'=$Array}

然后,您可以根据需要将其转换为 JSON 并获得:

{
    "versions":  [
                     {
                         "Name1":  "1.0.0"
                     },
                     {
                         "Name2":  "3.10.0"
                     }
                 ]
}

这就是你要找的,对吧?或者,如果你真的想要它在一行:

PS C:\> ($Versions|convertto-json).split() -join ""

{"versions":[{"Name1":"1.0.0"},{"Name2":"3.10.0"}]}

要完全按照您的第一个示例进行格式化,我们必须摆脱我想围绕该结果的 { } ,您可以使用 Trim() 这样做:

PS C:\> ($Versions|convertto-json).trim("{}").split() -join ""

"versions":[{"Name1":"1.0.0"},{"Name2":"3.10.0"}]

编辑:好的,所以您只需要根据需要添加对象作为其他对象的属性值,就像我在示例中将数组设置为对象中的值一样。

我认为了解需要做什么的最简单方法是举个例子(减去最后一个逗号,因为这会引发错误),并将其通过管道传输到 ConvertFrom-JSON 并为其分配一个变量。然后你可以看到它是如何在 Powersehll 中形成的。一旦我这样做了(我将变量命名为 $JSON),我可以看到 $JSON 有 1 个 NoteProperty of 'fields'。NoteProperty 有 3 个 NoteProperties,分别是“somefield”、“someobject”和“versions”。当我这样做时,$JSON.fields|Get-Member我会发现更多关于这些的信息。

somefield 只是一个字符串。这将很容易处理。

someobject 是一个 PSCustomObject,基本上是一个 HashTable,其中 name=foobar。

版本只是显示它是一个 System.Object,所以我将执行 $JSON.fields.versions.GetType(),它显示 basetpe 是 System.Array。查看版本后,它看起来像是一个包含 1 个对象的数组,并且该对象有一个 note 属性,它是一个字符串(就像我们拥有的第一个对象一样)。

所以,有两种方法可以做到这一点。您可以尝试在线创建对象和数组,也可以提前制作它们,从最深的嵌套层开始,然后逐步向上。稍后我会向你展示。

$name = [PSCustomObject]@{'name'='1.0'}
$versions=@($name)
$Someobject = [PSCustomObject]@{'name'='foobar'}
$Fields = [PSCustomObject]@{
        'somefields'='somevalue'
        'someobject'=$someobject
        'versions'=$versions}
$NewJSON = [PSCustomObject]@{'Fields'=$fields}
$NewJSON | ConvertTo-Json
于 2014-08-15T20:36:48.860 回答