Java XML Validation: How to Validate an XML Document against an XSD

4 min readJul 1, 2023

Introducing our Java XML Validation Project! Master the art of validating XML effortlessly against XSD in a Java environment. Gain hands-on experience, ensuring the integrity and conformity of your data.

1. Introduction

Introducing our Java XML Validation Project! Gain hands-on experience in validating XML documents against XSD with ease. This project serves as a practical guide, equipping you with the necessary knowledge and tools to ensure the integrity and conformity of your XML data in a Java environment. Discover the simplicity of our step-by-step approach, which walks you through the entire validation process. Master the art of validating XML effortlessly and unlock a new level of confidence in your data. Join us on this journey as we empower you to harness the power of XML validation in your Java projects.

2. Generating Java Classes from XSD

For this exercise, we will be using an XSD from w3schools

To be able to generate the Java classes from XSD, we will be using Eclipse Enterprise Edition. IntelliJ can also do it with the Jakarta plugin, but Eclipse performs better, especially when dealing with XJB files.


Eclipse JAXB Classes Generator

Generated Classes

3. Dependencies



4. Core Classes

To run the validations and throw the appropriate exception or name of the tag where a constraint is violated, we will need the following classes.

4.1 ResourceResolver

To import an external XSD, for example, if we will be using the XML digital signature.

<xs:import namespace="" schemaLocation="xmldsig-core-schema.xsd"/>
public class ResourceResolver implements LSResourceResolver {

private static final Logger LOGGER = LoggerFactory.getLogger(ResourceResolver.class);

public LSInput resolveResource(String type, String namespaceURI, String publicId, String systemId, String baseURI) {

// note: in this sample, the XSD's are expected to be in the root of the classpath
InputStream resourceAsStream = this.getClass().getClassLoader().getResourceAsStream("xsd/" + systemId);
return new Input(publicId, systemId, resourceAsStream);

static class Input implements LSInput {

private String publicId;

private String systemId;

public String getStringData() {

String textDataFromFile;

try {
BufferedReader bufferReader = new BufferedReader(new InputStreamReader(inputStream));
StringBuilder stringBuilder = new StringBuilder();
String eachStringLine;

while ((eachStringLine = bufferReader.readLine()) != null) {
textDataFromFile = stringBuilder.toString();

return textDataFromFile;

} catch (IOException e) {
LOGGER.error("Fail reading from inputStream={}", e.getMessage());
return null;

4.2 SaxErrorHandler

For us to be able to know the tag where a constraint exception is thrown, we need to define a custom exception that accepts an XMLStreamReader object where we can get the localName property.

public class SaxErrorHandler implements ErrorHandler {

private XMLStreamReader reader;

public SaxErrorHandler(XMLStreamReader reader) {
this.reader = reader;

public void error(SAXParseException e) {

public void fatalError(SAXParseException e) {

public void warning(SAXParseException e) {

throw new XmlValidationException(reader.getLocalName());

4.3 Miscellaneous Classes

We will also be needing utility classes for:

  • Creating a JAXBElement
  • Convert JAXBElement to XMLStreamReader
  • Defining the correct marshaller object

These classes are all available in the project.

4.4 XmlSchemaValidator Interface

And finally, the interface that pieces together all components to do the validation.

default void validateXMLSchema(String xsdPath, JAXBElement<?> xml) {

Validator validator = null;
try {
SchemaFactory factory = SchemaFactory.newInstance(XMLConstants.W3C_XML_SCHEMA_NS_URI);
factory.setProperty(XMLConstants.ACCESS_EXTERNAL_DTD, "");
factory.setProperty(XMLConstants.ACCESS_EXTERNAL_SCHEMA, "");
factory.setResourceResolver(new ResourceResolver());

Schema schema = factory.newSchema(ResourceUtils.getFile(xsdPath));
validator = schema.newValidator();
XMLStreamReader xmlStreamReader = asStreamReader(xml);

ErrorHandler errorHandler = new SaxErrorHandler(xmlStreamReader);

validator.validate(new StAXSource(xmlStreamReader));

} catch (IOException | SAXException | JAXBException | XMLStreamException e) {

var xmlEx = getXmlValidationExceptionIfPresent(e);
throw new InvalidXmlException(xmlEx.getLocalName(), e);

5. Source Code / Git Repository

The complete source code for this project is available for my sponsors at

Sponsorship link:

Project Screenshot




Open for Collaboration | Senior Java Backend Developer