or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

basic-validation.mdcli.mdconfiguration.mdextensions.mdformat-validation.mdindex.mdsyntax-validation.md

syntax-validation.mddocs/

0

# Syntax Validation

1

2

Dedicated functionality for validating JSON Schema syntax without performing instance validation. The syntax validator ensures that schemas conform to the JSON Schema specification structure and rules before they are used for instance validation.

3

4

## Capabilities

5

6

### SyntaxValidator

7

8

Standalone validator for checking JSON Schema syntax and structure.

9

10

```java { .api }

11

/**

12

* Validator for JSON Schema syntax without instance validation

13

*/

14

public final class SyntaxValidator {

15

/**

16

* Check if schema has valid syntax

17

* @param schema JsonNode containing the JSON schema to validate

18

* @return true if schema syntax is valid, false otherwise

19

*/

20

public boolean schemaIsValid(JsonNode schema);

21

22

/**

23

* Validate schema syntax and return detailed report

24

* @param schema JsonNode containing the JSON schema to validate

25

* @return ProcessingReport with validation results and error details

26

* @throws ProcessingException if syntax validation processing fails

27

*/

28

public ProcessingReport validateSchema(JsonNode schema) throws ProcessingException;

29

30

/**

31

* Get underlying processor for advanced usage

32

* @return Processor for schema tree validation

33

*/

34

public Processor<ValueHolder<SchemaTree>, ValueHolder<SchemaTree>> getProcessor();

35

}

36

```

37

38

**Usage Examples:**

39

40

```java

41

import com.fasterxml.jackson.databind.JsonNode;

42

import com.fasterxml.jackson.databind.ObjectMapper;

43

import com.github.fge.jsonschema.processors.syntax.SyntaxValidator;

44

import com.github.fge.jsonschema.main.JsonSchemaFactory;

45

import com.github.fge.jsonschema.core.report.ProcessingReport;

46

47

// Get syntax validator from factory

48

JsonSchemaFactory factory = JsonSchemaFactory.byDefault();

49

SyntaxValidator syntaxValidator = factory.getSyntaxValidator();

50

51

// Simple boolean validation

52

ObjectMapper mapper = new ObjectMapper();

53

JsonNode validSchema = mapper.readTree("{\n" +

54

" \"type\": \"object\",\n" +

55

" \"properties\": {\n" +

56

" \"name\": { \"type\": \"string\" },\n" +

57

" \"age\": { \"type\": \"integer\", \"minimum\": 0 }\n" +

58

" },\n" +

59

" \"required\": [\"name\"]\n" +

60

"}");

61

62

boolean isValid = syntaxValidator.schemaIsValid(validSchema);

63

System.out.println("Schema is valid: " + isValid); // true

64

65

// Detailed validation report

66

ProcessingReport report = syntaxValidator.validateSchema(validSchema);

67

if (report.isSuccess()) {

68

System.out.println("Schema syntax is correct");

69

} else {

70

System.out.println("Schema syntax errors:");

71

for (ProcessingMessage message : report) {

72

System.out.println(" " + message.getMessage());

73

}

74

}

75

76

// Validate invalid schema

77

JsonNode invalidSchema = mapper.readTree("{\n" +

78

" \"type\": \"object\",\n" +

79

" \"properties\": {\n" +

80

" \"age\": { \"type\": \"integer\", \"minimum\": \"not-a-number\" }\n" +

81

" }\n" +

82

"}");

83

84

ProcessingReport invalidReport = syntaxValidator.validateSchema(invalidSchema);

85

if (!invalidReport.isSuccess()) {

86

System.out.println("Syntax errors found:");

87

for (ProcessingMessage message : invalidReport) {

88

System.out.println(" Path: " + message.asJson().get("instance").get("pointer"));

89

System.out.println(" Error: " + message.getMessage());

90

}

91

}

92

```

93

94

## Schema Syntax Requirements

95

96

### Draft v4 Schema Structure

97

```java

98

// Valid Draft v4 schema structure

99

{

100

"$schema": "http://json-schema.org/draft-04/schema#", // Optional

101

"type": "object", // Root type

102

"properties": { // Object properties

103

"name": { "type": "string" },

104

"age": { "type": "integer", "minimum": 0 }

105

},

106

"required": ["name"], // Required properties

107

"additionalProperties": false // Additional property control

108

}

109

```

110

111

### Draft v3 Schema Structure

112

```java

113

// Valid Draft v3 schema structure

114

{

115

"$schema": "http://json-schema.org/draft-03/schema#", // Optional

116

"type": "object",

117

"properties": {

118

"name": { "type": "string" },

119

"age": { "type": "integer", "minimum": 0 }

120

},

121

"required": ["name"], // Different required syntax

122

"additionalProperties": false

123

}

124

```

125

126

## Common Syntax Validation Scenarios

127

128

### Example 1: Pre-validation Schema Check

129

```java

130

/**

131

* Validate schema syntax before using it for instance validation

132

*/

133

public JsonSchema createSchemaWithValidation(JsonNode schemaNode) throws ProcessingException {

134

JsonSchemaFactory factory = JsonSchemaFactory.byDefault();

135

SyntaxValidator syntaxValidator = factory.getSyntaxValidator();

136

137

// Check syntax first

138

ProcessingReport syntaxReport = syntaxValidator.validateSchema(schemaNode);

139

if (!syntaxReport.isSuccess()) {

140

StringBuilder errors = new StringBuilder("Schema syntax errors:\n");

141

for (ProcessingMessage message : syntaxReport) {

142

errors.append(" ").append(message.getMessage()).append("\n");

143

}

144

throw new ProcessingException(errors.toString());

145

}

146

147

// Safe to create schema instance

148

return factory.getJsonSchema(schemaNode);

149

}

150

```

151

152

### Example 2: Schema Validation Service

153

```java

154

/**

155

* Service for validating multiple schemas

156

*/

157

public class SchemaValidationService {

158

private final SyntaxValidator syntaxValidator;

159

160

public SchemaValidationService() {

161

this.syntaxValidator = JsonSchemaFactory.byDefault().getSyntaxValidator();

162

}

163

164

public ValidationResult validateSchemas(List<JsonNode> schemas) {

165

List<String> errors = new ArrayList<>();

166

List<JsonNode> validSchemas = new ArrayList<>();

167

168

for (int i = 0; i < schemas.size(); i++) {

169

JsonNode schema = schemas.get(i);

170

ProcessingReport report = syntaxValidator.validateSchema(schema);

171

172

if (report.isSuccess()) {

173

validSchemas.add(schema);

174

} else {

175

StringBuilder schemaErrors = new StringBuilder();

176

schemaErrors.append("Schema ").append(i).append(" errors:\n");

177

for (ProcessingMessage message : report) {

178

schemaErrors.append(" ").append(message.getMessage()).append("\n");

179

}

180

errors.add(schemaErrors.toString());

181

}

182

}

183

184

return new ValidationResult(validSchemas, errors);

185

}

186

187

public boolean isValidSchema(JsonNode schema) {

188

return syntaxValidator.schemaIsValid(schema);

189

}

190

}

191

192

public class ValidationResult {

193

private final List<JsonNode> validSchemas;

194

private final List<String> errors;

195

196

public ValidationResult(List<JsonNode> validSchemas, List<String> errors) {

197

this.validSchemas = validSchemas;

198

this.errors = errors;

199

}

200

201

public boolean hasErrors() {

202

return !errors.isEmpty();

203

}

204

205

public List<JsonNode> getValidSchemas() {

206

return validSchemas;

207

}

208

209

public List<String> getErrors() {

210

return errors;

211

}

212

}

213

```

214

215

### Example 3: Schema Development Tool

216

```java

217

/**

218

* Development utility for interactive schema validation

219

*/

220

public class SchemaDebugger {

221

private final SyntaxValidator syntaxValidator;

222

private final ObjectMapper mapper;

223

224

public SchemaDebugger() {

225

this.syntaxValidator = JsonSchemaFactory.byDefault().getSyntaxValidator();

226

this.mapper = new ObjectMapper();

227

}

228

229

public void debugSchema(String schemaJson) {

230

try {

231

JsonNode schema = mapper.readTree(schemaJson);

232

System.out.println("=== Schema Syntax Validation ===");

233

System.out.println("Schema:");

234

System.out.println(mapper.writerWithDefaultPrettyPrinter().writeValueAsString(schema));

235

System.out.println();

236

237

ProcessingReport report = syntaxValidator.validateSchema(schema);

238

239

if (report.isSuccess()) {

240

System.out.println("✓ Schema syntax is valid");

241

System.out.println("Schema version: " + detectSchemaVersion(schema));

242

} else {

243

System.out.println("✗ Schema syntax errors found:");

244

for (ProcessingMessage message : report) {

245

JsonNode messageJson = message.asJson();

246

String pointer = messageJson.get("instance").get("pointer").asText();

247

String error = message.getMessage();

248

249

System.out.println(" Location: " + (pointer.isEmpty() ? "/" : pointer));

250

System.out.println(" Error: " + error);

251

System.out.println();

252

}

253

}

254

255

} catch (Exception e) {

256

System.out.println("✗ Invalid JSON: " + e.getMessage());

257

}

258

}

259

260

private String detectSchemaVersion(JsonNode schema) {

261

JsonNode schemaUri = schema.get("$schema");

262

if (schemaUri != null) {

263

return schemaUri.asText();

264

}

265

return "Draft v4 (default)";

266

}

267

268

public static void main(String[] args) {

269

SchemaDebugger debugger = new SchemaDebugger();

270

271

// Test valid schema

272

String validSchema = "{\n" +

273

" \"type\": \"object\",\n" +

274

" \"properties\": {\n" +

275

" \"name\": { \"type\": \"string\" }\n" +

276

" }\n" +

277

"}";

278

debugger.debugSchema(validSchema);

279

280

// Test invalid schema

281

String invalidSchema = "{\n" +

282

" \"type\": \"object\",\n" +

283

" \"properties\": {\n" +

284

" \"age\": { \"type\": \"integer\", \"minimum\": \"invalid\" }\n" +

285

" }\n" +

286

"}";

287

debugger.debugSchema(invalidSchema);

288

}

289

}

290

```

291

292

## Syntax Validation Rules

293

294

### Type Validation Rules

295

- `type` must be a string or array of strings

296

- Valid types: `"null"`, `"boolean"`, `"object"`, `"array"`, `"number"`, `"integer"`, `"string"`

297

- Array types must contain unique values

298

299

### Numeric Constraint Rules

300

- `minimum`, `maximum` must be numbers

301

- `exclusiveMinimum`, `exclusiveMaximum` must be booleans (Draft v4) or numbers (Draft v6+)

302

- `multipleOf` must be a positive number

303

304

### String Constraint Rules

305

- `minLength`, `maxLength` must be non-negative integers

306

- `pattern` must be a valid regular expression string

307

308

### Array Constraint Rules

309

- `minItems`, `maxItems` must be non-negative integers

310

- `items` must be an object or array of objects

311

- `additionalItems` must be boolean or object

312

313

### Object Constraint Rules

314

- `properties` must be an object with schema values

315

- `patternProperties` must be an object with regex keys and schema values

316

- `additionalProperties` must be boolean or object

317

- `required` must be array of strings (Draft v4) or boolean (Draft v3)

318

- `minProperties`, `maxProperties` must be non-negative integers

319

320

## Integration with Validation

321

322

```java

323

/**

324

* Complete validation pipeline with syntax checking

325

*/

326

public class CompleteValidationPipeline {

327

private final JsonSchemaFactory factory;

328

private final SyntaxValidator syntaxValidator;

329

330

public CompleteValidationPipeline() {

331

this.factory = JsonSchemaFactory.byDefault();

332

this.syntaxValidator = factory.getSyntaxValidator();

333

}

334

335

public ProcessingReport validateWithSyntaxCheck(JsonNode schema, JsonNode instance) throws ProcessingException {

336

// Step 1: Validate schema syntax

337

ProcessingReport syntaxReport = syntaxValidator.validateSchema(schema);

338

if (!syntaxReport.isSuccess()) {

339

return syntaxReport; // Return syntax errors

340

}

341

342

// Step 2: Create schema and validate instance

343

JsonSchema jsonSchema = factory.getJsonSchema(schema);

344

return jsonSchema.validate(instance);

345

}

346

347

public ValidationResult completeValidation(JsonNode schema, JsonNode instance) {

348

try {

349

ProcessingReport report = validateWithSyntaxCheck(schema, instance);

350

return new ValidationResult(report.isSuccess(), report);

351

} catch (ProcessingException e) {

352

return new ValidationResult(false, null, e.getMessage());

353

}

354

}

355

}

356

```

357

358

## Best Practices

359

360

1. **Early Validation**: Always validate schema syntax before instance validation

361

2. **Error Reporting**: Use detailed reports to provide clear feedback on syntax issues

362

3. **Development Workflow**: Integrate syntax validation into schema development tools

363

4. **Performance**: Cache syntax validation results for frequently used schemas

364

5. **Version Awareness**: Be explicit about JSON Schema version compatibility

365

6. **Testing**: Include syntax validation in your schema test suites