Fork me on GitHub

Generating Schemas

This guide explains how to generate XML Schema (XSD) and JSON Schema from Metaschema modules.

The Metaschema tools can generate:

  • XML Schema (XSD) - For validating XML documents
  • JSON Schema - For validating JSON documents
<build>
    <plugins>
        <plugin>
            <groupId>dev.metaschema.java</groupId>
            <artifactId>metaschema-maven-plugin</artifactId>
            <version>3.0.0.M2</version>
            <executions>
                <!-- Generate XML Schema -->
                <execution>
                    <id>generate-xsd</id>
                    <goals>
                        <goal>generate-xsd</goal>
                    </goals>
                    <configuration>
                        <metaschemaDir>src/main/metaschema</metaschemaDir>
                        <includes>
                            <include>my-model_metaschema.xml</include>
                        </includes>
                        <outputDirectory>/home/runner/work/metaschema-java/metaschema-java/target/schemas/xsd</outputDirectory>
                    </configuration>
                </execution>

                <!-- Generate JSON Schema -->
                <execution>
                    <id>generate-json-schema</id>
                    <goals>
                        <goal>generate-json-schema</goal>
                    </goals>
                    <configuration>
                        <metaschemaDir>src/main/metaschema</metaschemaDir>
                        <includes>
                            <include>my-model_metaschema.xml</include>
                        </includes>
                        <outputDirectory>/home/runner/work/metaschema-java/metaschema-java/target/schemas/json</outputDirectory>
                    </configuration>
                </execution>
            </executions>
        </plugin>
    </plugins>
</build>
# Generate all schemas
mvn generate-resources

# Generate only XSD
mvn metaschema:generate-xsd

# Generate only JSON Schema
mvn metaschema:generate-json-schema
metaschema-cli generate-schema --as=xsd model_metaschema.xml output.xsd
metaschema-cli generate-schema --as=json model_metaschema.xml output.json
import dev.metaschema.core.model.IModule;
import dev.metaschema.core.model.MetaschemaLoader;
import dev.metaschema.schemagen.xml.XmlSchemaGenerator;

import java.io.Writer;
import java.nio.file.Files;
import java.nio.file.Path;

// Load module
MetaschemaLoader loader = new MetaschemaLoader();
IModule module = loader.load(Path.of("model_metaschema.xml"));

// Generate XSD
XmlSchemaGenerator generator = new XmlSchemaGenerator();
try (Writer writer = Files.newBufferedWriter(Path.of("output.xsd"))) {
    generator.generateFromModule(module, writer);
}
import dev.metaschema.core.model.IModule;
import dev.metaschema.core.model.MetaschemaLoader;
import dev.metaschema.schemagen.json.JsonSchemaGenerator;

import java.io.Writer;
import java.nio.file.Files;
import java.nio.file.Path;

// Load module
MetaschemaLoader loader = new MetaschemaLoader();
IModule module = loader.load(Path.of("model_metaschema.xml"));

// Generate JSON Schema
JsonSchemaGenerator generator = new JsonSchemaGenerator();
try (Writer writer = Files.newBufferedWriter(Path.of("output.json"))) {
    generator.generateFromModule(module, writer);
}

Generated XSD includes:

  • Complex types for assemblies
  • Simple types for fields and flags
  • Element declarations
  • Namespace declarations
  • Documentation from Metaschema descriptions
<!-- Generated XSD example -->
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"
           targetNamespace="http://example.com/ns/model">

    <xs:element name="catalog" type="catalog-type"/>

    <xs:complexType name="catalog-type">
        <xs:annotation>
            <xs:documentation>A collection of controls.</xs:documentation>
        </xs:annotation>
        <xs:sequence>
            <xs:element ref="metadata" minOccurs="1"/>
            <xs:element ref="control" minOccurs="0" maxOccurs="unbounded"/>
        </xs:sequence>
        <xs:attribute name="uuid" type="uuid-type" use="required"/>
    </xs:complexType>

</xs:schema>

Generated JSON Schema includes:

  • Object definitions for assemblies
  • Property definitions for fields and flags
  • Required property arrays
  • Type constraints
  • Description annotations
{
  "$schema": "http://json-schema.org/draft-07/schema#",
  "definitions": {
    "catalog": {
      "type": "object",
      "description": "A collection of controls.",
      "properties": {
        "uuid": {
          "type": "string",
          "format": "uuid"
        },
        "metadata": {
          "$ref": "#/definitions/metadata"
        },
        "controls": {
          "type": "array",
          "items": {
            "$ref": "#/definitions/control"
          }
        }
      },
      "required": ["uuid", "metadata"]
    }
  }
}
import javax.xml.XMLConstants;
import javax.xml.transform.stream.StreamSource;
import javax.xml.validation.Schema;
import javax.xml.validation.SchemaFactory;
import javax.xml.validation.Validator;

import java.io.File;

import org.xml.sax.SAXException;

SchemaFactory factory = SchemaFactory.newInstance(
    XMLConstants.W3C_XML_SCHEMA_NS_URI);
Schema schema = factory.newSchema(new File("output.xsd"));
Validator validator = schema.newValidator();

try {
    validator.validate(new StreamSource(new File("document.xml")));
    System.out.println("Valid!");
} catch (SAXException e) {
    System.err.println("Invalid: " + e.getMessage());
}

Using a JSON Schema validator library (e.g., networknt/json-schema-validator):

import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.networknt.schema.JsonSchema;
import com.networknt.schema.JsonSchemaFactory;
import com.networknt.schema.SpecVersion;
import com.networknt.schema.ValidationMessage;

import java.io.File;
import java.util.Set;

ObjectMapper objectMapper = new ObjectMapper();
JsonSchemaFactory factory = JsonSchemaFactory.getInstance(
    SpecVersion.VersionFlag.V7);
JsonSchema schema = factory.getSchema(
    objectMapper.readTree(new File("output.json")));

JsonNode document = objectMapper.readTree(new File("document.json"));
Set<ValidationMessage> errors = schema.validate(document);

if (errors.isEmpty()) {
    System.out.println("Valid!");
} else {
    errors.forEach(err -> System.err.println(err.getMessage()));
}
<configuration>
    <metaschemaDir>src/main/metaschema</metaschemaDir>
    <includes>
        <include>model_metaschema.xml</include>
    </includes>
    <outputDirectory>/home/runner/work/metaschema-java/metaschema-java/target/schemas/xsd</outputDirectory>
</configuration>
<configuration>
    <metaschemaDir>src/main/metaschema</metaschemaDir>
    <includes>
        <include>model_metaschema.xml</include>
    </includes>
    <outputDirectory>/home/runner/work/metaschema-java/metaschema-java/target/schemas/json</outputDirectory>
</configuration>
Aspect Schema Validation Constraint Validation
Format XSD/JSON Schema Metaschema constraints
Scope Structure, types Business rules
Cross-references Limited Full support
Custom rules No Metapath expressions
Standard tools Yes Metaschema tools

Recommendation: Use both for comprehensive validation:

  1. Schema for structural validation
  2. Constraints for semantic validation

Symptom: Generated schema references undefined types

Fix: Ensure all imported modules are accessible

Symptom: Multiple schemas with same namespace

Fix: Use unique namespaces per module

Symptom: Schemas not found after generation

Fix: Check outputDirectory configuration

  1. Generate during build - Include in Maven lifecycle
  2. Version schemas - Track schema changes
  3. Publish schemas - Make available for consumers
  4. Use both schema types - Support XML and JSON users
  5. Include in documentation - Reference from API docs

Continue learning about the Metaschema Java Tools with these related guides: