Java XML Validation: How to Validate an XML Document against an XSD
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
2. Generating Java Classes from XSD
3. Dependencies
<dependency>
<groupId>com.fasterxml.jackson.dataformat</groupId>
<artifactId>jackson-dataformat-xml</artifactId>
</dependency>
<dependency>
<groupId>jakarta.activation</groupId>
<artifactId>jakarta.activation-api</artifactId>
<version>2.1.1</version>
</dependency>
<dependency>
<groupId>jakarta.xml.bind</groupId>
<artifactId>jakarta.xml.bind-api</artifactId>
<version>${jakarta.version}</version>
</dependency>
<dependency>
<groupId>org.glassfish.jaxb</groupId>
<artifactId>jaxb-runtime</artifactId>
<version>${jakarta.version}</version>
<scope>runtime</scope>
</dependency>
4. Core Classes
4.1 ResourceResolver
<xs:import namespace="http://www.w3.org/2000/09/xmldsig#" 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) {
stringBuilder.append(eachStringLine).append("\n");
}
textDataFromFile = stringBuilder.toString();
return textDataFromFile;
} catch (IOException e) {
LOGGER.error("Fail reading from inputStream={}", e.getMessage());
return null;
}
}
...
4.2 SaxErrorHandler
public class SaxErrorHandler implements ErrorHandler {
private XMLStreamReader reader;
public SaxErrorHandler(XMLStreamReader reader) {
this.reader = reader;
}
@Override
public void error(SAXParseException e) {
warning(e);
}
@Override
public void fatalError(SAXParseException e) {
warning(e);
}
@Override
public void warning(SAXParseException e) {
throw new XmlValidationException(reader.getLocalName());
}
}
4.3 Miscellaneous Classes
- Creating a JAXBElement
- Convert JAXBElement to XMLStreamReader
- Defining the correct marshaller object
4.4 XmlSchemaValidator Interface
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.setErrorHandler(errorHandler);
validator.validate(new StAXSource(xmlStreamReader));
} catch (IOException | SAXException | JAXBException | XMLStreamException e) {
var xmlEx = getXmlValidationExceptionIfPresent(e);
throw new InvalidXmlException(xmlEx.getLocalName(), e);
}
}




Post a Comment