当前位置: 首页 > 面试题库 >

通过Powershell中的变量解析/访问嵌套的JSON /哈希表数据时出现问题

慕仲渊
2023-03-14
问题内容

我正在尝试通过Powershell动态解析和构建一些我将要提供的传入JSON文件的数据结构(将采用非标准结构),然后处理这些文件中的数据并交给他们转到下一步。

作为其中的一部分,我正在尝试将JSON文件的数据结构构建为实质上的数据路径列表,以便我解析并从中获取数据,以便可以处理嵌套JSON的数组。对象等。到目前为止,一切都很好。

我遇到某种Powershell特性的地方是通过变量处理2级以上的深度。让我给你一个漂亮的代码块来演示这个问题…

# Generate a Quick JSON file with different data types & levels
[object]$QuickJson = @'
{
    "Name" : "I am a JSON",
    "Version" : "1.2.3.4",
    "SomeBool" : true,
    "NULLValue" : null,
    "ArrayOfVersions" : [1.0,2.0,3.0],
    "MyInteger" : 69,
    "NestedJSON" : {
        "Version" : 5.0,
        "IsReady" : false
    },
    "DoubleNestedJSON" : {
        "FirstLevel" : 1,
        "DataValue" : "I am at first nested JSON level!",
        "Second_JSON_Level" : {
            "SecondLevel" : 2,
            "SecondDataValue" : "I am on the 2nd nested level"
        }
    }
}
'@

# Import our JSON file into Powershell
[object]$MyPSJson = ConvertFrom-Json -InputObject $QuickJson
# Two quick string variables to access our JSON data paths
[string]$ShortJsonPath = "Name"
[string]$NestedJsonPath = "NestedJson.Version"
# Long string to access a double-nested JSON object
[string]$LongNestedJsonPath = "DoubleNestedJSON.Second_JSON_Level.SecondDataValue"

# Both of these work fine
Write-Host ("JSON Name (Direct) ==> " + $MyPSJson.Name)
Write-Host ("JSON Name (via Variable) ==> " + $MyPSJson.$ShortJsonPath)

# The following way to access a single nested Json Path works fine
Write-Host ("Nested JSON Version (via direct path) ==> " + $MyPSJson.NestedJson.Version)
# And THIS returns an empty line / is where I fall afoul of something in Powershell
Write-Host ("Nested JSON Version (via variable) ==> " + $MyPSJson.$NestedJsonPath)

# Other things I tried -- all returning an empty line / failing in effect
Write-Host ("Alternate Nested JSON Version ==> " + $($MyPSJson.$NestedJsonPath))
Write-Host ("Alternate Nested JSON Version ==> " + $MyPSJson.$($NestedJsonPath))
Write-Host ("Alternate Nested JSON Version ==> " + $($MyPSJson).$($NestedJsonPath))

# Similarly, while THIS works...
$MyPSJson | select-object -Property NestedJSON
# This will fail / return me nothing
$MyPSJson | select-object -Property NestedJSON.Version

…在对此进行了大量研究时,我遇到了一个将其转换为Hashtable的建议-
可悲的是,它存在相同的问题。因此,使用上面的代码片段,下面的代码会将JSON对象转换为哈希表。

# Same problem with a hash-table if constructed from the JSON file...
[hashtable]$MyHash = @{}
# Populate $MyHash with the data from our quickie JSON file...
$QuickJson | get-member -MemberType NoteProperty | Where-Object{ -not [string]::IsNullOrEmpty($QuickJson."$($_.name)")} | ForEach-Object {$MyHash.add($_.name, $QuickJson."$($_.name)")}

# ... and even then -- $MyHash."$($NestedJsonPath)" -- fails, while a single level deep string works fine in the variable! :(

因此,很明显,我遇到了Powershell内部逻辑问题的“某些方面”,但是我不能说Powershell在为什么如此方面过分帮助。添加“
-debug”或类似命令以增加详细程度并没有帮助我们弄清这一点。

我怀疑这类似于本文(https://blogs.technet.microsoft.com/heyscriptingguy/2011/10/16/dealing-
with-powershell-hash-table-
quirks/)中提出的内容与变量。

在Powershell语言规范中找不到任何明显的东西我没有运气(据我所知,3.0仍然是此处最新的东西)-https:
//www.microsoft.com/zh-cn/downloads/details.aspx? id =
36389)。它可能在那里,我可能会想念它。

任何有关如何使Powershell与其搭配使用的建议都将不胜感激。我不确定Powershell如何/为什么使用简单的字符串就可以,但是在这里似乎与’something.somethingelse’类型的字符串有关。

谢谢。

原件的其他说明和附录:

似乎有几个问题需要攻击。一种是“处理单个嵌套级别”。为此,“快速修复”似乎正在使用“ Invoke-Expression”来解析该语句,例如(重要-
注意第一个变量的反勾号!):

iex "`$MyPSJson.$NestedJsonPath"

使用Invoke-Expression还可用于多嵌套情况:

iex "`$MyPSJson.$LongNestedJsonPath"

提到的另一种方法是使用多个选择语句…但是我无法使它与多嵌套对象一起使用(Powershell出于某种原因似乎无法正确解析这些对象)。

因此,例如在这种情况下:

($MyComp | select $_.DoubleNestedJSON | select FirstLevel)

Powershell返回

FirstLevel    
----------

…而不是实际数据值。所以-目前看来,由于Powershell显然无法解决选择问题,因此selects不适用于多层嵌套对象吗?


问题答案:

为什么这不起作用

当您在字符串中提供所需的属性时,就像这样

[string]$NestedJsonPath = "NestedJson.Version"

Powershell寻找一个名为的属性NestedJSon.Version。它实际上并没有遍历属性,而是在寻找包含句点的字符串文字。实际上,如果我这样向您的JSON添加这样的属性。

[object]$QuickJson = @'
{
    "Name" : "I am a JSON",
    "Version" : "1.2.3.4",
    "SomeBool" : true,
    "NULLValue" : null,
    "ArrayOfVersions" : [1.0,2.0,3.0],
    "MyInteger" : 69,
    "NestedJSON.Version" : 69,
    "NestedJSON" : {
        "Version" : 5.0,
        "IsReady" : false
    }
}

我现在得到了价值,就像这样:

>$MyPSJson.$NestedJsonPath
69

取回值的最佳方法是使用两个单独的变量,如下所示。

$NestedJson = "NestedJson"
$property   = "Version"

>$MyPSJson.$NestedJson.$property
5.0

或者,您也可以使用select语句,如下面的原始答案所示。

$MyPSJson | select $_.NestedJSON | select Version
Version
-------
1.2.3.4

如果您使用多个Select-Object语句,它们将丢弃其他属性,并允许您更轻松地向下钻取您想要的值。



 类似资料:
  • 问题内容: 我正在尝试使用C#处理一些json格式的数据,但是在确定解决该问题的正确方法时遇到了一些问题。我的问题是json格式的数据将采用未知格式(我知道听起来很奇怪,请继续阅读)。基本上,json格式的数据将是名称/值对的一些集合,其中值可能是也可能不是嵌套的名称/值对的数组。为了使事情变得更加有趣,名称/值对数组的嵌套可以在无限时继续进行。 例如:我可能有一些看起来像……的数据。 不幸的是,

  • 问题内容: 我正在尝试使用zippopotam.us获取特定城市的邮政编码。我有下面的代码可以正常工作,但是当我尝试访问返回的密钥时 完整的JSON输出: 谢谢你的帮助。 问题答案: 我没有意识到第一个嵌套元素实际上是一个数组。正确访问邮政编码密钥的方法如下:

  • 问题内容: 假设我有json数据,例如 现在我正在从该json数据访问字段,例如: 如何以最有效的方式从给定的json数据访问第三个字段()? 不起作用 一种可能是我使用for循环构造字符串,然后进行eval评估,但是有没有有效的方法呢? 问题答案: 老实说,我无法理解您的问题。JSON已经结构化了,为什么需要更改结构? 在您的情况下,我将按以下方式访问它: 如果碰巧希望 遍历 数据,则需要: 更

  • 本文向大家介绍Powershell使用嵌套哈希表实例 嵌套哈希表的2种写法例子,包括了Powershell使用嵌套哈希表实例 嵌套哈希表的2种写法例子的使用技巧和注意事项,需要的朋友参考一下 嵌套哈希表对于多维数组是一个更好选择。这种存储方式将更易于管理。请看: 也可以使用这种写法,也许更好: 脚本定义了一个用户,你可以查看一下这个用户的全部信息:   你将更容易获得里面单个信息:

  • 问题内容: 我仍在Go的学习过程中,但是在涉及JSON响应数组时遇到了麻烦。每当我尝试访问“对象”数组的嵌套元素时,Go都会抛出异常(类型接口{}不支持索引) 出了什么问题?将来如何避免犯此错误? http://play.golang.org/p/duW-meEABJ 编辑:固定链接 问题答案: 如错误所述,接口变量不支持索引。您将需要使用类型断言来转换为基础类型。 当解码为变量时,JSON模块将

  • 问题内容: 如果我将函数名称存储为字符串在Hashtable中。 有没有办法通过存储的字符串访问函数? 编辑恐怕我在CLDC1.1 / MIDP2.0上工作的平台不支持反射。 有什么解决方法? 问题答案: 只需使用一长串else-ifs: (尽管我通常不喜欢尝试在源代码中进行垂直对齐,但我认为在这种情况下这样做是值得的。) 在映射中存储函子是一种替代方法,对于许多MIDP应用程序,bu可能会增加对