-
Notifications
You must be signed in to change notification settings - Fork 7.1k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
ConvertFrom-Json returns array with extra null element, if comments are outside the root element. #21203
Comments
Might be related to #14553 |
Currect workaround:
|
What you have there is a thing called not a json file. Comments are not part of the JSON file specification. Relying on comments in what you think are json files is just storing up trouble depending on the strictness of the parser you use. The simplest approach is to (a) stick to the JSON specification (b) use text elements within the structure as your comments. |
I would appreciate it, if you would first check the specifications of ComvertFrom-Json before writing google-able general information about common knowledge like what exactly JSON is:
|
PowerShell is moving from Newtonsoft.Json to System.Text.Json and the grammer rules and capabilities are not the same for the extensions to JSON, hence why I recommend keeping to the standard to save you the trouble of downstream problems such as this. |
I see the null if you try a round trip. The null does not appear in the Format-Table output.
and the Out-String solves the problem
So one could say that the issue is not one of ConvertFrom-Json parsing a single JSON document, it is part of the piping. This is the list of strings in the input pipeline to ConvertFrom-Json.
The comment is on its own line so is a complete self contained JSON-with-comments document, it can be parsed in it's entirety and written to the output. The remaining lines are a group of lines referring to the same JSON document, so the parser has not seen the closing "}" so there is still more to come in subsequent lines. So the ambiguity is two-fold,
I suggest that ConvertFrom-JSON really sees two separate JSON documents. If the comment is moved to within the brackets, the problem goes away
|
Yes,
|
I already mentioned above that there is a workaround using a single string (out-string or gc -raw) but this is not the solution. According to the documentation of ConvertFrom-Json, the current implementation has a bug. |
Stil, ConvertFrom-Json is designed to generate one single object representation (can also be an array) based on an array of string lines or a single multi line string. Parsing separate input items (JSON documents) which are not written as JSON arrays (wrapped in brackets, separated by commas) should not result in a JSON array, but a parsing error. ConverFrom-Json could simply ignore what comes after comment literals and add no data to the object structure during parsing. |
Lets start with Get-Content and note that each line of a text file is its own record in the output pipeline. I suggest that any change is going to make the matter worse. ConvertFrom-JSON does work with multiple JSON documents in different record records and outputs each as a record With the file
This is not a JSON file, it would need wrapping square brackets and commas between the objects. It is however a sequence of well-formed JSON files. This is output as multiple PSCustomObjects
And if you round trip them, then ConvertTo-JSON turns the list of records into a JSON array.
So ConvertFrom-JSON as it is today will read multiple JSON files and output each as a PSCustomObject a single string containing a "// Comment on top level" is a complete self-contained JSON document as far as it is concerned, it had no parsing errors and gave back null, so that is what was written to the output pipeline. If people are relying on the behaviour of ConvertFrom-JSON to parse each record as a unique JSON file then I don't see what change can be made to the cmdlet. Now if you look at the document page it says
That suggests that is what you should be doing via Out-String or using Raw on Get-Content, where you are telling ConvertFrom-JSON what the boundaries of the document are, and there is exactly one in the input.
|
Showing each JSON document as its own record
Then show the output of ConvertFrom-JSON
Also a comment by itself is a complete JSON document, giving you a null, the following gives no parse errors.
the output record is there....
just like
Now if you try
You get in a mess
So although "// comment" was sufficient to be a document by itself, when that was a prefix it assumed the following was all one document. So there looks like there is some behaviour to try and join the individual lines into a single document. |
According to RFC7159 you are right. According to the older and more common understanding of what a JSON file should be (only object or array as in RFC4627), you are wrong. I would recommend to add a note to the documentation to raise awareness for this gotcha. Something like "always read the file in raw mode ". Another suggestion is, to introduce a new CmdLet called Import-Json analogous to Import-Csv that implicitly does the same thing. |
I was just trying to describe the existing behaviour and it happily parses individual elements, so let's say ConvertFrom-JSON is consistent with RFC7159 from the point of view of what constitutes a complete JSON document.
But of course, neither of RFC7159 or RFC4627 describe any comment encoding, other than
|
Let me try to provide a summary:
|
Prerequisites
Steps to reproduce
Having a json file containing this:
should become a PSObject or Hashtable, when imported using Get-Content and then piped through ConvertFrom-Json, but the result is an array with a null as first element and the PSObject/Hashtable as the second element!
Expected behavior
Comment lines have to be ignored, not be included as null elements.
Actual behavior
Comments on top level are interpreted as null elements like a "{}".
Error details
No response
Environment data
Visuals
No response
The text was updated successfully, but these errors were encountered: