I'm trying to use HJSON C# library for PowerShell: https://github.com/hjson/hjson-cs I've successfully compiled the dll, put it into a folder and added the type via standard procedure:
#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")
I'm trying to follow examples to get the basics:
Read method: 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
but the output is missing values:
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>
So I can't see values. Why it doesn't work like JSON objects?
And when I try to iterate through keys:
foreach ( $item in $jsonObject) {
$item.Key, $item.Value
}
I got this:
The following exception occurred while trying to enumerate the collection: "The operation is invalid due to the current state of the object. "
I'm sure I'm missing something, but I don't know c# enough to know what to do.
The library is just written in a way that doesn't work great with how PowerShell displays data it doesn't have format information for.
Why
JsonValue(the type emitted byHjson.Load) is more or less a dictionary ofstringtoJsonPrimitive(or moreJsonValuefor nesting).The reason you don't see any values when you output the variable is because PowerShell by default just converts objects to a string. The
JsonValueto string conversion is just an empty string, so it appears like a null value, but it's a full object.The reason it throws the
InvalidOperationExceptionreferencing enumeration is because PowerShell tries to enumerate anything that implementsIEnumerable. But,JsonPrimitivewill throw when you try to enumerate it if the real value of the object isn't an array.Solution
Individual values
If you want to get an individual value, you can call the
JsonPrimitive.ToValuemethod. This will convert theJsonPrimitiveto the equivalent .NET type.The problem with this is it will only work on keys you know are primitives. That means to do a full conversion to a normal displayable type you would have to enumerate the
JsonValue, check if it's aJsonPrimitiveorJsonObject, then either callToValueor recurse into the nested object.Full conversion
A simpler approach might be to just convert it to json as PowerShell is a lot better at handling that
The
Savemethod takes a path, a stream, or aTextWriter. TheStringWriterobject is just an easy way to get a string from something that accepts aTextWriter.How to tell?
If you're ever faced with an object that you think should have a value but displays like it doesn't have a value, there's a solid chance it just doesn't display right in PowerShell. In this scenario, the easiest way you could have tested would be trying some of these: