1

我正在尝试为 PowerShell 使用 HJSON C# 库:https ://github.com/hjson/hjson-cs 我已成功编译 dll,将其放入文件夹并通过标准过程添加类型:

#LOAD
$scriptRoot = Split-Path $script:psEditor.GetEditorContext().CurrentFile.Path

$FilePath = ( Get-Item .\Hjson.dll ).FullName
[System.Reflection.Assembly]::LoadFrom("$FilePath")

[Hjson.IJsonReader]::new()

[Hjson.hjson]::Load("$scriptRoot\test.hjson")

我正在尝试通过示例来了解基础知识:
读取方法:https ://github.com/hjson/hjson-cs#read

# var jsonObject = HjsonValue.Load(filePath).Qo();

$jsonTempData = [Hjson.HjsonValue]::Load("$scriptRoot\test.hjson")
$jsonObject = [Hjson.JsonUtil]::Qo($jsonTempData)
$jsonObject

但输出缺少值:

PS D:\OneDrive\PS-HJSON> $jsonObject

Key       Value
---       -----
hello
text
quote
otherwise
abc-123
commas
but
trailing
multiline
number
negative
yes
no
null
array
array2


PS D:\OneDrive\PS-HJSON>

所以我看不到价值。为什么它不像 JSON 对象那样工作?

当我尝试遍历键时:

foreach ( $item in $jsonObject) {
    $item.Key, $item.Value
}

我懂了:

尝试枚举集合时发生以下异常:“由于对象的当前状态,该操作无效。”

我确定我遗漏了一些东西,但我对 c# 的了解还不够,不知道该怎么做。

4

1 回答 1

1

该库的编写方式不适用于 PowerShell 如何显示它没有格式信息的数据。

为什么

  • JsonValue(由 发出的类型Hjson.Load)或多或少是stringto的字典JsonPrimitive(或更多JsonValue用于嵌套)。

  • 输出变量时看不到任何值的原因是 PowerShell 默认情况下只是将对象转换为字符串。到字符串的JsonValue转换只是一个空字符串,所以它看起来像一个空值,但它是一个完整的对象。

  • 它抛出InvalidOperationException引用枚举的原因是 PowerShell 尝试枚举任何实现IEnumerable. 但是,JsonPrimitive如果对象的实际值不是数组,则会在您尝试枚举它时抛出。

解决方案

个人价值观

如果要获取单个值,可以调用该JsonPrimitive.ToValue方法。这会将 转换JsonPrimitive为等效的 .NET 类型。

$jsonObject = [Hjson.HjsonValue]::Load("myFile.hjson")
$jsonObject['MyKey'].ToValue()

这样做的问题是它只适用于你知道是原语的键。这意味着要完全转换为正常的可显示类型,您必须枚举JsonValue,检查它是否是JsonPrimitiveor JsonObject,然后调用ToValue或递归到嵌套对象中。

完全转换

一种更简单的方法可能是将其转换为 json,因为 PowerShell 在处理它方面要好得多

$jsonObject = [Hjson.HjsonValue]::Load("myFile.hjson")
$stringWriter = [System.IO.StringWriter]::new()
$jsonObject.Save($stringWriter, [Hjson.Stringify]::Plain)
$hjsonAsPSObject = $stringWriter.GetStringBuilder().ToString() | ConvertFrom-Json

Save方法采用路径、流或TextWriter. 该StringWriter对象只是从接受TextWriter.

怎么讲?

如果您曾经遇到一个您认为应该有值但显示为没有值的对象,那么它很可能无法在 PowerShell 中正确显示。在这种情况下,您可以测试的最简单的方法是尝试其中一些:

# Shows you the objects type, or if it really is $null it will throw
$jsonObject['jsonKey'].GetType()

# This will tell you the properties and methods available on an object
# but in this case it would throw due to the enumeration funk.
$jsonObject['jsonKey'] | Get-Member

# This gets around the enumeration issue.  Because there's no pipeline,
# Get-Member gives you the members for the type before enumeration.
Get-Member -InputObject ($jsonObject['jsonKey'])
于 2018-04-12T21:15:59.613 回答