1

I would like to validate my Json against a Json Schema in Windows PowerShell

For PowerShell 7, you might use Test-Json for this:

$Json = @'
{
  "name": "James",
  "hobbies": [".NET", "Blogging", "Reading", "Xbox", "LOLCATS"]
}
'@

$JsonSchema = @'
{
  "description": "A person",
  "type": "object",
  "required": ["name", "hobbies"],
  "properties":
  {
    "name": {"type":"string"},
    "hobbies": {
      "type": "array",
      "items": {"type":"string"}
    }
  }
}
'@

Test-Json -Json $Json -Schema $JsonSchema
True

But when I try to do something similar with the Newtonsoft.Json class (standard available in PowerShell 7), I get an error:

$Schema = [Newtonsoft.Json.Schema.JsonSchema]::Parse($JsonSchema)
$JObject = [Newtonsoft.Json.Linq.JObject]::Parse($Json)
$JObject.IsValid($Schema)

OperationStopped: C:\Users\Gebruiker\GDrive\Scripts\PowerShell\_JIO\Yaml\Test-Yaml.ps1:31
Line |
  31 |  $JObject.IsValid($Schema)
     |  ~~~~~~~~~~~~~~~~~~~~~~~~~
     | Target type System.Collections.IEnumerator is not a value type or a non-abstract class. (Parameter 'targetType')

How can I fix this or workaround this?

References:

iRon
  • 20,463
  • 10
  • 53
  • 79

1 Answers1

0

I can't get the official JToken.IsValid() examples working in Windows PowerShell either, but I found that using a "validating reader" works:

using namespace System.IO
using namespace Newtonsoft.Json

# Create a read around the JSON string
$reader = [JsonTextReader]::new([StringReader]::new($Json))

# Create a validator around the reader, attach governing schema
$validator = [JsonValidatingReader]::new($reader)
$validator.Schema = $schema

# Create a serializer
$serializer = $serializer = [JsonSerializer]::new()

try {
  # attempt to deserializer input json via validator
  $null = $serializer.Deserialize($validator)

  # schema validation must have succeeded
}
catch [Newtonsoft.Json.Schema.JsonSchemaException] {
  # schema validation must have failed
}
catch {
  # something else went wrong
}
finally {
  # Clean up
  $reader, $validator |% Dispose
}
Mathias R. Jessen
  • 157,619
  • 12
  • 148
  • 206
  • thanks for the answer but unfortunately it appears to also have issues with the newtonsoft object format. This didn't appear from my orginal [mcve]. I have updated the question with a new schema, including an additinal array: `"required": ["name", "hobbies"],` which fails with an error: `Cannot convert value "{ ... }" to type "Newtonsoft.Json.Schema.JsonSchema". Error: "Can not convert Array to Boolean` – iRon Mar 16 '23 at 18:27
  • I think I need to try this approach with [System.Text.Json](https://learn.microsoft.com/dotnet/standard/serialization/system-text-json/migrate-from-newtonsoft). Later this weekend... – iRon Mar 16 '23 at 18:56