Search code examples
c++jsonrapidjson

rapidjson Schema Document multiple roots error


I am using RapidJSON to parse JSON files. I am trying to use a rapidjson::SchemaDocument to make a JSON schema to validate received JSON files.

But, when I try to construct a schema document that was generated by website liquid-technologies.com, "error code 2" is received, which indicates that the JSON (schema) document I am trying to parse has multiple roots, even though it has only one.

Here is the schema document I am trying to parse:

{
  "$schema": "http://json-schema.org/draft-04/schema#",
  "type": "object",
  "properties": {
    "title": {
      "type": "string"
    },
    "pay": {
      "type": "number"
    },
    "country": {
      "type": "string"
    },
    "employer": {
      "type": "object",
      "properties": {
        "name": {
          "type": "string"
        },
        "workforce": {
          "type": "integer"
        },
        "officelocation": {
          "type": "string"
        }
      },
      "required": [
        "name",
        "workforce",
        "officelocation"
      ]
    },
    "location": {
      "type": "string"
    },
    "flexibleHours": {
      "type": "boolean"
    },
    "description": {
      "type": "string"
    }
  },
  "required": [
    "title",
    "pay",
    "country",
    "employer",
    "location",
    "flexibleHours",
    "description"
  ]
}

And here is my code:

std::string schemaJson = readFile("../jsonschemas/postjobschema.json");
    rapidjson::Document sd;
    if (sd.Parse(schemaJson.c_str()).HasParseError()) {
        std::cout << "Schema has parse errors" << std::endl;
        if (sd.GetParseError() == rapidjson::kParseErrorDocumentRootNotSingular)
            std::cout << "There are multiple roots" << std::endl;
    }

Is my schema incorrect, or am I doing something wrong?


Solution

  • I think you schema is correct, but there is something wrong with your code.

    I have tested your scehma json and a mock input json with rapidjson's example/schemavalidator, it turns out everything works well.

    input.json:

    {
        "title": "foo",
        "pay": 100,
        "country": "US",
        "employer": { "name": "bar", "workforce": 12, "officelocation": "UK"},
        "location": "CA",
        "flexibleHours": true,
        "description": "hello"
    }
    
    ./bin/schemavalidator /tmp/schema.json < /tmp/input.json
    
    Input JSON is valid.
    

    Would you like to read your schema json file with rapidjson::FileReadStream?

        // Read a JSON schema from file into Document
        Document d;
        char buffer[4096];
    
        {
            FILE *fp = fopen(argv[1], "r");
            if (!fp) {
                printf("Schema file '%s' not found\n", argv[1]);
                return -1;
            }
            FileReadStream fs(fp, buffer, sizeof(buffer));
            d.ParseStream(fs);
            if (d.HasParseError()) {
                fprintf(stderr, "Schema file '%s' is not a valid JSON\n", argv[1]);
                fprintf(stderr, "Error(offset %u): %s\n",
                    static_cast<unsigned>(d.GetErrorOffset()),
                    GetParseError_En(d.GetParseError()));
                fclose(fp);
                return EXIT_FAILURE;
            }
            fclose(fp);
        }