XMLUnit Core is a comprehensive XML testing library for Java that provides powerful tools for comparing XML documents, validating XML against schemas, and evaluating XPath expressions.
XML validation against various schema languages including W3C XML Schema, RelaxNG, and Schematron with detailed validation error reporting and custom error handling. XMLUnit provides a unified API for validating both XML schemas themselves and XML instance documents against schemas.
The main entry point for creating validators for different schema languages.
/**
* Create validator for specified schema language
* @param language - Schema language URI (use Languages constants)
* @returns Validator instance for the specified language
*/
public static Validator forLanguage(String language);
public abstract class Validator {
/** Set multiple schema sources for validation */
public void setSchemaSources(Source... s);
/** Set single schema source for validation */
public void setSchemaSource(Source s);
/** Validate the schema itself for correctness */
public abstract ValidationResult validateSchema();
/** Validate XML instance against configured schemas */
public abstract ValidationResult validateInstance(Source instance);
}Usage Examples:
import org.xmlunit.validation.Validator;
import org.xmlunit.validation.Languages;
import org.xmlunit.validation.ValidationResult;
import org.xmlunit.builder.Input;
// W3C XML Schema validation
Validator xmlSchemaValidator = Validator.forLanguage(Languages.W3C_XML_SCHEMA_NS_URI);
xmlSchemaValidator.setSchemaSource(Input.fromFile("person.xsd").build());
ValidationResult result = xmlSchemaValidator.validateInstance(
Input.fromString("<person><name>John</name><age>30</age></person>").build()
);
if (result.isValid()) {
System.out.println("Document is valid");
} else {
System.out.println("Validation errors:");
for (ValidationProblem problem : result.getProblems()) {
System.out.println("- " + problem.getMessage());
}
}
// RelaxNG validation
Validator relaxNgValidator = Validator.forLanguage(Languages.RELAXNG_NS_URI);
relaxNgValidator.setSchemaSource(Input.fromFile("schema.rng").build());
ValidationResult relaxResult = relaxNgValidator.validateInstance(
Input.fromFile("document.xml").build()
);
// Multiple schema files
Validator multiSchemaValidator = Validator.forLanguage(Languages.W3C_XML_SCHEMA_NS_URI);
multiSchemaValidator.setSchemaSources(
Input.fromFile("common.xsd").build(),
Input.fromFile("specific.xsd").build(),
Input.fromURI("http://example.com/external.xsd").build()
);Constants for supported schema validation languages.
public class Languages {
/** W3C XML Schema language URI */
public static final String W3C_XML_SCHEMA_NS_URI = "http://www.w3.org/2001/XMLSchema";
/** DTD validation language URI */
public static final String XML_DTD_NS_URI = "http://www.w3.org/TR/REC-xml";
/** RELAX NG schema language URI */
public static final String RELAXNG_NS_URI = "http://relaxng.org/ns/structure/1.0";
}Comprehensive validation result information including success status and detailed problem reports.
public class ValidationResult {
/**
* Create validation result
* @param valid - Whether validation succeeded
* @param problems - Collection of validation problems found
*/
public ValidationResult(boolean valid, Iterable<ValidationProblem> problems);
/** Check if validation succeeded without errors */
public boolean isValid();
/** Get all validation problems (errors and warnings) */
public Iterable<ValidationProblem> getProblems();
}Usage Examples:
ValidationResult result = validator.validateInstance(xmlSource);
// Check overall validity
if (result.isValid()) {
System.out.println("Document is valid");
} else {
System.out.println("Document has validation errors");
}
// Process individual problems
for (ValidationProblem problem : result.getProblems()) {
System.out.println("Type: " + problem.getType());
System.out.println("Line: " + problem.getLine());
System.out.println("Column: " + problem.getColumn());
System.out.println("Message: " + problem.getMessage());
System.out.println("---");
}
// Count different problem types
int errorCount = 0;
int warningCount = 0;
for (ValidationProblem problem : result.getProblems()) {
if (problem.getType() == ValidationProblem.ProblemType.ERROR) {
errorCount++;
} else if (problem.getType() == ValidationProblem.ProblemType.WARNING) {
warningCount++;
}
}
System.out.println("Errors: " + errorCount + ", Warnings: " + warningCount);Detailed information about individual validation issues.
public class ValidationProblem {
/** Get the type of validation problem */
public ProblemType getType();
/** Get line number where problem occurred */
public int getLine();
/** Get column number where problem occurred */
public int getColumn();
/** Get descriptive message for the problem */
public String getMessage();
/** Get the exception that caused this problem (if any) */
public Throwable getException();
/** Problem severity types */
public enum ProblemType {
ERROR, // Validation error that makes document invalid
WARNING // Validation warning that doesn't affect validity
}
}XMLUnit provides multiple validator implementations for different validation approaches.
/** JAXP-based validator using javax.xml.validation API */
public class JAXPValidator extends Validator {
// Uses standard JAXP validation framework
// Supports W3C XML Schema, RelaxNG (if provider available)
}
/** Parser-based validator using validation-enabled parsing */
public class ParsingValidator extends Validator {
// Uses DocumentBuilder with validation enabled
// May have different behavior than JAXPValidator
}Implementation Selection:
The Validator.forLanguage() method automatically selects the most appropriate implementation based on the schema language and available JAXP providers. Users typically don't need to choose implementations directly.
Advanced error handling and validation customization options.
public class ValidationHandler {
// Internal error handler used by validators
// Collects validation problems during processing
}Error Handling Examples:
try {
Validator validator = Validator.forLanguage(Languages.W3C_XML_SCHEMA_NS_URI);
validator.setSchemaSource(Input.fromFile("schema.xsd").build());
ValidationResult result = validator.validateInstance(
Input.fromFile("document.xml").build()
);
// Process results...
} catch (IllegalArgumentException e) {
System.err.println("Invalid schema language or configuration: " + e.getMessage());
} catch (RuntimeException e) {
if (e.getCause() instanceof SAXException) {
System.err.println("Schema parsing error: " + e.getMessage());
} else if (e.getCause() instanceof IOException) {
System.err.println("I/O error reading schema or document: " + e.getMessage());
} else {
System.err.println("Validation error: " + e.getMessage());
}
}Common validation scenarios and best practices.
Single Schema Validation:
// Validate against single W3C XML Schema
Validator validator = Validator.forLanguage(Languages.W3C_XML_SCHEMA_NS_URI);
validator.setSchemaSource(Input.fromFile("person.xsd").build());
ValidationResult result = validator.validateInstance(
Input.fromString("<person><name>John</name></person>").build()
);Multiple Schema Validation:
// Validate against multiple related schemas
Validator validator = Validator.forLanguage(Languages.W3C_XML_SCHEMA_NS_URI);
validator.setSchemaSources(
Input.fromFile("base-types.xsd").build(),
Input.fromFile("person.xsd").build(),
Input.fromFile("address.xsd").build()
);
ValidationResult result = validator.validateInstance(xmlDocument);Remote Schema Validation:
// Validate against schema from URL
Validator validator = Validator.forLanguage(Languages.W3C_XML_SCHEMA_NS_URI);
validator.setSchemaSource(
Input.fromURI("http://example.com/schemas/person.xsd").build()
);
ValidationResult result = validator.validateInstance(xmlDocument);Inline Schema Validation:
// Schema defined as string (useful for testing)
String schemaContent = """
<?xml version="1.0"?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema">
<xs:element name="person">
<xs:complexType>
<xs:sequence>
<xs:element name="name" type="xs:string"/>
<xs:element name="age" type="xs:int"/>
</xs:sequence>
</xs:complexType>
</xs:element>
</xs:schema>
""";
Validator validator = Validator.forLanguage(Languages.W3C_XML_SCHEMA_NS_URI);
validator.setSchemaSource(Input.fromString(schemaContent).build());
ValidationResult result = validator.validateInstance(
Input.fromString("<person><name>Alice</name><age>25</age></person>").build()
);Schema Self-Validation:
// Validate the schema itself before using it
Validator validator = Validator.forLanguage(Languages.W3C_XML_SCHEMA_NS_URI);
validator.setSchemaSource(Input.fromFile("questionable-schema.xsd").build());
// First validate the schema
ValidationResult schemaResult = validator.validateSchema();
if (!schemaResult.isValid()) {
System.err.println("Schema is invalid:");
for (ValidationProblem problem : schemaResult.getProblems()) {
System.err.println("- " + problem.getMessage());
}
return;
}
// Then validate instances against the valid schema
ValidationResult instanceResult = validator.validateInstance(xmlDocument);RelaxNG Validation:
// RelaxNG validation (requires RelaxNG provider)
Validator relaxValidator = Validator.forLanguage(Languages.RELAXNG_NS_URI);
relaxValidator.setSchemaSource(Input.fromFile("schema.rng").build());
ValidationResult result = relaxValidator.validateInstance(xmlDocument);Validation integrates seamlessly with XMLUnit's input and testing capabilities.
// Validate generated XML from JAXB
Person person = new Person("John", 30);
Source jaxbXml = Input.fromJaxb(person).build();
Validator validator = Validator.forLanguage(Languages.W3C_XML_SCHEMA_NS_URI);
validator.setSchemaSource(Input.fromFile("person.xsd").build());
ValidationResult result = validator.validateInstance(jaxbXml);
// Validate XML after transformation
Source originalXml = Input.fromFile("input.xml").build();
Source transformedXml = Transform.source(originalXml)
.usingStylesheet(Input.fromFile("transform.xsl").build())
.build();
ValidationResult transformResult = validator.validateInstance(transformedXml);
// Use validation in test assertions (with testing framework integration)
// This would typically be done with XMLUnit's Hamcrest matchers or AssertJ assertionsInstall with Tessl CLI
npx tessl i tessl/maven-org-xmlunit--xmlunit-core