使用Powershell从Json结构提取值时出现问题
使用Powershell,我将一个json片段返回到我的第一个变量中(这总是很好) 然后我将convert函数调用为一个temp变量,如下所示使用Powershell从Json结构提取值时出现问题,json,powershell,Json,Powershell,使用Powershell,我将一个json片段返回到我的第一个变量中(这总是很好) 然后我将convert函数调用为一个temp变量,如下所示 $ResponseBody = ConvertFrom-Json $whatStatusJsonContent; message_id ---------- 9093813071099257562 它将Json放入这样一个漂亮的小数据结构中 $ResponseBody = ConvertFrom-Json $wha
$ResponseBody = ConvertFrom-Json $whatStatusJsonContent;
message_id
----------
9093813071099257562
它将Json放入这样一个漂亮的小数据结构中
$ResponseBody = ConvertFrom-Json $whatStatusJsonContent;
message_id
----------
9093813071099257562
我可以通过调用此函数从中选择所需的值
$nMessage_id = $ResponseBody.message_id;
通常,这很好,我将值放入第二个变量中
$nMessage_id = 9093813071099257562
问题是:有时我在$nMessage_id中什么也得不到,即使$whatStatusJsonContent肯定被记录为从函数正确返回了Json
我的问题是:我必须从Json转换,还是可以从第一个变量中读取原始值
组合解决方案:感谢@mklement()和@Bernard Moeskops
# Initialise variables...
$nMessage_id = "";
$whatStatusJsonContent = "";
# Function https://abc.googleapis.com/abc/load call here and returns...
$whatStatusJsonContent = '{"message_id":9093813071099257562}'
$ResponseBody = ConvertFrom-Json $whatStatusJsonContent;
if($ResponseBody.message_id){
# ConvertFrom-Json got the value!
$nMessage_id = $ResponseBody.message_id
}else{
# ConvertFrom-Json didn't work!
$nMessage_id = = ($whatStatusJsonContent -split '[:}]')[1]
}
您必须转换它,以便PowerShell能够理解它。它将从字符串转换为PSCustomObject。只需询问前后变量的类型即可进行检查
$ResponseBody.message_id.GetType()
如果有时输出为空,则可以执行以下操作:
if($ResponseBody.message_id){
$nMessage_id = $ResponseBody.message_id
}else{
throw "No message id found"
}
希望这有帮助。您的代码没有明显的错误 应按预期工作,并返回带有
.message\u id
属性的[pscustomobject]
实例
在您的示例中,message\u id
JSON属性值是一个整数,对于它,ConvertTo JSON
自动选择一个合适的整数数据类型,如下所示:最小的有符号类型>=[int]
(System.Int32
)[1],它可以容纳值([int]
->[long]
(System.Int64
)->[decimal]
(System.decimal
);需要注意的是,如果该值甚至不能放入[decimal]
,则使用-increact-[double]
。[2]
对于问题中的示例JSON,选择了[long]
在后续评论中,您声明:
该例程每小时发出1000多个调用,对于大多数调用来说,Json会返回,$nMessage_id
生成得非常完美。然后,突然间,$nMessage_id
为空,即使Json被记录为恢复正常。因此,在Json的转换器
或$ResponseBody.message_id
中的某个地方,该值将丢失
我没有解释,但如果(无论出于何种原因,convertfromjson
是罪魁祸首,您可以尝试字符串操作作为一种解决方法来提取消息ID,看看这是否有帮助:
$whatStatusJsonContent = '{"message_id":9093813071099257562}'
# Extract the message_id property value as a *string*
# (which you can cast to a numeric type if/as needed).
$message_id = ($whatStatusJsonContent -split '[:}]')[1]
上面在$message_id
中存储内容为9093813071099257562
的字符串;请注意,正如所写的,输入字符串的格式必须与上面关于空格的格式完全相同;虽然可以使文本解析更加健壮,但不必担心格式变化是使用专用解析器(如convertfromjson
)的一个很好的理由
另一个选项是尝试另一个JSON解析器,看看这是否有帮助。 是.NET世界中卓越的JSON解析器(现在是PowerShell Core中JSON cmdlet的基础): 注意:Json.NET类似于PowerShell内核中Json的
转换,当一个数字太大而无法放入[long]
时,它也可以使用任意大的[bigint]
类型
使用Json.NET程序集比使用ConvertFrom-Json
cmdlet具有更好的性能
在PowerShell Core中,可以按原样运行上述代码(程序集已预加载);在Windows PowerShell中,您必须通过上面的链接下载程序包,并使用add Type-LiteralPath
将程序集(NewtonSoft.Json.dll
)添加到会话中
[1] 奇怪的是,在PowerShell Core中,从(至少)v6.2.0开始,选择的最小类型是[long]
(System.Int64
)
[2] 更有用的是,从(至少)v6.2.0开始,PowerShell Core会在值不再适合[long]
时创建一个任意大的[bigint]
(System.Numerics.biginger
)实例;也就是说,完全跳过了[decimal]
类型。我非常怀疑这是问题所在。我认为在变量为空时,它实际上不会返回任何数据。。您需要做的是使用Powershell_ise.exe,并确保在脚本中添加以下内容如果(!$ResponseBody.message_id){Write Host“响应主体为空”}#现在在Write Host部分放置一个制动点(F9)。运行脚本,身体一空,你就会到达制动点。现在脚本暂停,您可以使用空的特定调用进行故障排除。希望这对我有所帮助,如果我需要进一步澄清,请告诉我。我唯一能想象的是,由于连接中断或其他原因,每一百万次回复都是空的?时代。当给定有效输入时,Json的ConvertFrom将始终工作。如果某个程序是固态编写的,它不会失败。然而,调用API有很多依赖关系。在您的情况下,很难排除故障。网络相关问题显然是罪魁祸首。您可以尝试收集更多的$ResponseBy.message_id,例如StatusCode,以及任何与例如200不同的时间来输出响应/错误。感谢@Bernard Moeskops的帮助,请参阅组合解决方案感谢@rangi;我很高兴你找到了一个有效的解决办法。了解问题的真正原因仍然是一件有趣的事情,例如,是否有一个来自Json的ConvertFrom
bug;您是否尝试过Json.NET替代方案,这样您就不必依赖文本解析了?如果有机会,我会尝试一下,这有点棘手,因为我可能无法将包上载到Azure无服务器环境中。干杯