Can patternProperties have object types and can I define them in definitions?

654 views
Skip to first unread message

Kim

unread,
Jan 20, 2015, 3:56:24 AM1/20/15
to json-schem...@googlegroups.com
Hi,

I'm having trouble getting a schema to work. I'm using patternProperties in a definition, but it doesn't seem to recognize the properties in my definition. Any help understanding where I went wrong would be appreciated. Thanks!


Here's my schema:    
{
    "type": "object",
    "patternProperties": {
        "^[a-z]+$": {"$ref": "#/definitions/relation"}
    },
    "definitions": {
        "relation": {
            "type": "object",
            "properties" : {
                "type": "string",
                "model": "string",
                "foreignKey": "string"
            }
        }
    }
}

And here's my input:
{
    "reviews": {
      "type": "hasMany",
      "model": "Review",
      "foreignKey": "authorId"
    },
    "orders": {
      "type": "hasMany",
      "model": "Order",
      "foreignKey": "customerId"
    }
}

But the validator gives me these errors:
[ {
  "level" : "fatal",
  "message" : "invalid JSON Schema, cannot continue\nSyntax errors:\n[ {\n  \"level\" : \"error\",\n  \"schema\" : {\n    \"loadingURI\" : \"#\",\n    \"pointer\" : \"/definitions/relation/properties/foreignKey\"\n  },\n  \"domain\" : \"syntax\",\n  \"message\" : \"JSON value is of type string, not a JSON Schema (expected an object)\",\n  \"found\" : \"string\"\n}, {\n  \"level\" : \"error\",\n  \"schema\" : {\n    \"loadingURI\" : \"#\",\n    \"pointer\" : \"/definitions/relation/properties/model\"\n  },\n  \"domain\" : \"syntax\",\n  \"message\" : \"JSON value is of type string, not a JSON Schema (expected an object)\",\n  \"found\" : \"string\"\n}, {\n  \"level\" : \"error\",\n  \"schema\" : {\n    \"loadingURI\" : \"#\",\n    \"pointer\" : \"/definitions/relation/properties/type\"\n  },\n  \"domain\" : \"syntax\",\n  \"message\" : \"JSON value is of type string, not a JSON Schema (expected an object)\",\n  \"found\" : \"string\"\n} ]",
  "info" : "other messages follow (if any)"
}, {
  "level" : "error",
  "schema" : {
    "loadingURI" : "#",
    "pointer" : "/definitions/relation/properties/foreignKey"
  },
  "domain" : "syntax",
  "message" : "JSON value is of type string, not a JSON Schema (expected an object)",
  "found" : "string"
}, {
  "level" : "error",
  "schema" : {
    "loadingURI" : "#",
    "pointer" : "/definitions/relation/properties/model"
  },
  "domain" : "syntax",
  "message" : "JSON value is of type string, not a JSON Schema (expected an object)",
  "found" : "string"
}, {
  "level" : "error",
  "schema" : {
    "loadingURI" : "#",
    "pointer" : "/definitions/relation/properties/type"
  },
  "domain" : "syntax",
  "message" : "JSON value is of type string, not a JSON Schema (expected an object)",
  "found" : "string"
} ]


Francis Galiegue

unread,
Jan 20, 2015, 4:14:03 AM1/20/15
to json-schem...@googlegroups.com
Hello,

On Tue, Jan 20, 2015 at 9:56 AM, Kim <wyko...@gmail.com> wrote:
> Hi,
>
> I'm having trouble getting a schema to work. I'm using patternProperties in
> a definition, but it doesn't seem to recognize the properties in my
> definition. Any help understanding where I went wrong would be appreciated.
> Thanks!
>

The problem is as mentioned in the error messages: your schema is
invalid (note the domain of errors: "syntax").

The problem lies in your "properties" keyword. The values for each
member of this keyword's value is a JSON Schema; but in your schema
they are not.

You write for instance:

> "properties" : {
> "type": "string",


But that is incorrect; "string" is not a JSON Schema. This should read:

"properties": {
"type": { "type": "string" }
}

etc etc.

--
Francis Galiegue, fgal...@gmail.com, https://github.com/fge
JSON Schema in Java: http://json-schema-validator.herokuapp.com
Parsers in pure Java: https://github.com/parboiled1/grappa (redde
Caesaris: https://github.com/sirthias)

Kim

unread,
Jan 20, 2015, 5:43:55 AM1/20/15
to json-schem...@googlegroups.com
Oh, great! That worked! I didn't think it was a schema problem because the schema box didn't tell me I had an invalid schema. 

Thanks

Kim

unread,
Jan 20, 2015, 9:10:31 AM1/20/15
to json-schem...@googlegroups.com
I thought I would answer the 2nd part of my question. Once the schema was syntactically correct, I figured out how to do it with 2 definitions. If there's a way to do it with only 1 definition, I would like to hear about it.

Final schema:
{
    "type": "object",
    "properties": {
       "relations" : {"$ref": "#/definitions/relations"}
   
},
    "definitions": {
       "relations" : {
           "patternProperties": {
               "^[a-z][A-Za-z0-9]+$": {"$ref": "#/definitions/relation"}
           },
           "additionalProperties": false
       },
       "relation": {
           "properties" : {
               "type": {"type":"string", "enum": ["hasMany"]},
               "model": {"type":"string"},
               "foreignKey": {"type":"string"}
           }
       }
   }
}

And my input is:
{
   "relations": {
    "reviews": {
      "type": "hasMany",
      "model": "Review",
      "foreignKey": "authorId"
    },
    "orders": {
      "type": "hasMany",
      "model": "Order",
      "foreignKey": "customerId"
    }
  }
}

Francis Galiegue

unread,
Jan 20, 2015, 10:35:22 AM1/20/15
to Kim, json-schem...@googlegroups.com
Hello,

On Tue, Jan 20, 2015 at 3:10 PM, Kim <wyko...@gmail.com> wrote:
> I thought I would answer the 2nd part of my question. Once the schema was
> syntactically correct, I figured out how to do it with 2 definitions. If
> there's a way to do it with only 1 definition, I would like to hear about
> it.
>

Well, you could do it with one definiton only if you just inlined
"relation"; now, it's entirely up to you. If you wish to reuse it
later then it's better to just leave the second definition.

One note, though:

[...]
> "relation": {
> "properties" : {
> "type": {"type":"string", "enum": ["hasMany"]},

No need for "type": "string" here. Values in "enum" use JSON equality.
If the value of the "type" member is _anything else_ but JSON String
"hasMany", the validation will fail.
Reply all
Reply to author
Forward
0 new messages