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