eclipsesource/play-json-schema-validator

Not sure how to use the library with multiple JSON schema files

Closed this issue · 2 comments

Hi
I am trying to validate my JSON with TinCan JSON schema from here

TinCan Schema

As you can see in folder 1.0.1 there are several json files reference each other.

And now, I may have a Statement object like this

{
    "actor": {...} // actor can be either Agent or Group and validated by Agent.json or Group.json
    "verb": {...}
    "object": {...}
}

How can I build a validator from several json schema files?

Thank you

@AlexTo Hi, please note that there was a minor mistake when using ids which I've fixed today with 0.9.5-M3. So for the following to work, please update. To answer your original question: you can use addSchema to make all involved schemas known to the validator. Here's a sample test case for starters, which can be improved upon (this assumes that the references JSON files are stored within a tincan resource folder on the classpath):

class TinCanSpec extends Specification { self =>

  import com.eclipsesource.schema.drafts.Version4

  val instance = JsonSource.fromString(
    """
      |{
      |  "actor": {
      |    "name": "Sally Glider",
      |    "mbox": "mailto:sally@example.com"
      |  },
      |  "verb": {
      |    "id": "http://adlnet.gov/expapi/verbs/experienced",
      |    "display": { "en-US": "experienced" }
      |  },
      |  "object": {
      |    "id": "http://example.com/activities/solo-hang-gliding",
      |    "definition": {
      |      "name": { "en-US": "Solo Hang Gliding" }
      |    }
      |  }
      |}
    """.stripMargin).get


  "Tin Can Spec" should {

    import Version4._

    def readSchema(filename: String) =
      JsonSource.schemaFromStream(self.getClass.getResourceAsStream(s"/tincan/$filename.json")).get

    "validate basic statement object" in {

      val validator = SchemaValidator(Some(Version4))
        .addSchema("#agent", readSchema("agent"))
        .addSchema("#group", readSchema("group"))
        .addSchema("#inversefunctional", readSchema("inversefunctional"))
        .addSchema("#mbox", readSchema("mbox"))
        .addSchema("#statement_base", readSchema("statement_base"))
        .addSchema("#statement_object", readSchema("statement_object"))
        .addSchema("#verb", readSchema("verb"))
        .addSchema("#languagemap", readSchema("languagemap"))
        .addSchema("#activity", readSchema("activity"))
        .addSchema("#activity_definition", readSchema("activity_definition"))
        .addSchema("#activityid", readSchema("activityid"))

      val result = validator.validate(readSchema("statement_base"), instance)
      result.isSuccess must beTrue
    }
  }
}

Thanks a lot, this seems to be a better solution.
After creating this issue, I ended up, modifying all the "$ref" in all the files.

For e.g.
"$ref": "#someschema" => "$ref": "classpath:/path/someschema.json"
The problem is I have to update all the JSON schema files which I don't want.

Also, there are some ref which I don't know how to deal with for .e.g I have the followign in activity.json
"id": {"$ref": "#activityid!core"},
And this is activityid.json

{
    "$schema": "http://json-schema.org/draft-04/schema#",
    "id": "#activityid",
    "type": "object",
    "required": ["activityId"],
    "properties": {
        "activityId": {
        "id": "#activityid!core",
        "type": "string",
        "format": "iri"
        }
    }
}

I will try your approach, thanks again