The javax.xml.validation
package provides an API for XML documents validation. The validation process verify that an XML document is an instance of a specified XML schema file or XSD file. In this example we are going to validate if the records.xml
file below ins an instance of the records.xsd
schema. First we will create the following XML file and an XSD file it should follow.
The XML file:
<?xml version="1.0" encoding="UTF-8"?>
<root>
<records>
<record>
<title>Brand New Eyes</title>
<artist>Paramore</artist>
<genre>Punk Rock</genre>
<year>2011</year>
</record>
<record>
<artist>Various Artist</artist>
<genre>Rock</genre>
<year/>
</record>
</records>
</root>
The XSD file:
<?xml version="1.0" encoding="UTF-8"?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" attributeFormDefault="unqualified"
elementFormDefault="qualified">
<xs:element name="root" type="rootType">
</xs:element>
<xs:complexType name="rootType">
<xs:sequence>
<xs:element name="records" type="recordsType"/>
</xs:sequence>
</xs:complexType>
<xs:complexType name="recordsType">
<xs:sequence>
<xs:element name="record" type="recordType" maxOccurs="unbounded" minOccurs="0"/>
</xs:sequence>
</xs:complexType>
<xs:complexType name="recordType">
<xs:sequence>
<xs:element type="xs:string" name="title"/>
<xs:element type="xs:string" name="artist"/>
<xs:element type="xs:string" name="genre"/>
<xs:element type="xs:short" name="year"/>
</xs:sequence>
</xs:complexType>
</xs:schema>
The code snippet below will handle the validation process in the following steps. In the main()
method we create the XMLValidator
instance and call the validate()
method and pass the XML file and the XSD file. Our validate()
method start by creating an instance of SchemaFactory
. The SchemaFactory.newInstance()
method return an instance of SchemaFactory
. In this example we are creating a W3C XML Schema.
The next step is to create a Schema
object by calling the schemaFactory.newSchema()
and pass the schema / XSD file. The Schema
object will allow us to create an instance of javax.xml.validation.Validator
by calling the schema.newValidator()
method. And finally to validate if the XML is valid we call validator.validate()
method and pass the XML file to be validated. If the XML is not valid, this validate()
method will throw exceptions.
The Java code:
package org.kodejava.xml;
import org.xml.sax.SAXException;
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 java.io.FileNotFoundException;
import java.io.IOException;
import java.net.URL;
import java.util.Objects;
public class XMLValidator {
public static final String XML_FILE = "records.xml";
public static final String SCHEMA_FILE = "records.xsd";
public static void main(String[] args) {
XMLValidator XMLValidator = new XMLValidator();
boolean valid = XMLValidator.validate(XML_FILE, SCHEMA_FILE);
System.out.printf("%s validation = %b.", XML_FILE, valid);
}
private boolean validate(String xmlFile, String schemaFile) {
SchemaFactory schemaFactory = SchemaFactory.newInstance(XMLConstants.W3C_XML_SCHEMA_NS_URI);
try {
Schema schema = schemaFactory.newSchema(new File(getResource(schemaFile)));
Validator validator = schema.newValidator();
validator.validate(new StreamSource(new File(getResource(xmlFile))));
return true;
} catch (SAXException | IOException e) {
e.printStackTrace();
return false;
}
}
private String getResource(String filename) throws FileNotFoundException {
URL resource = getClass().getClassLoader().getResource(filename);
Objects.requireNonNull(resource);
return resource.getFile();
}
}
- How do I get number of each day for a certain month in Java? - September 8, 2024
- How do I get operating system process information using ProcessHandle? - July 22, 2024
- How do I sum a BigDecimal property of a list of objects using Java Stream API? - July 22, 2024
Hi,
I get a
java.lang.NullPointerException
when trying to callvalidator.validate(new StreamSource(new File(getResource(xmlFile))));
. It can not find the resource for the second attempt.Hi Paul,
To prevent the error make sure you have the
.xsd
file in yourresources
directory (in Maven project structure). TheClassLoader.getResource()
will try to find the resource files on your classpath.Dear Mr Wayan,
I had also face the same problem too. Can you please explain in more detail how to solve this error?
try using this line.
Its gives error: Exception: cvc-elt.1: Cannot find the declaration of element ‘root’.
Hello Vinit,
Do you have the
root
element in your XML file as in the example above? The error says it cannot file an element calledroot
.Hi Wayan,
Thank you for the sharing code.
I encounter error below, may I know why?
I had found out the error. Kindly delete the above comment. Sorry for the inconvenient caused.
Hi yTze, glad that you’ve found out the error 🙂
Is there any way to do it without storing file into resource directory?
Hi Aakash,
You can directly load the file if you know the exact location of the file. Something like:
Error: Could not find or load main class
Hi Shakti,
Your code get an exception because it could not load the
xml
andxsd
files. The code example above written as a maven project and I’ve placed the files under aresources
directory. See the structure below.If you don’t use a maven project just replace the call to
getResource()
method with the full path of yourxml
andxsd
file location.This stops after getting an error. It is not giving the next error or list of all error in the file.
Hi Shakti,
If you could post the error message I might able to help you with the problem you are facing.
I am getting below error.
Hi Ved, can you show us your xsd file content?
Some errors is XML file, put all the path resource as Wayan Saryada said, but correct the XML file in the section of line 11, 14 and ends the of this form.
Thank you very much, worked perfectly! For the ones who are having the
NullPointerException
, try to delete these lines:and replace them with:
respectively. This worked for me.
Hi, many thanks for this article. I am facing an issue while validating schema. I have my user defined XSD file where in I have user defined “xmlns” and “target namespace” along with “xmlns:xs”. While I am using this code, even if xml is not correct as per this xsd, it is getting pass which is wrong. Request you to please help!
Hi Bunny, can you provide the XSD and the XML document for me to look?
Hi Wayan,
I’ve used the same piece of code you have mentioned above to validate my XML with the XSD. But it’s still giving me a null pointer exception. I have given the XML & XSD directory directly as you have mentioned in the comments who were having the same issue.
Kindly let me know how I can resolve this issue?
I am using Spring Boot application with Jdk17. After updating the latest Docker image, I am getting the schema validation errors twice. It is showing duplicate errors for few xsd validation errors. Any idea on this issue? How we can resolve this issue?
Hi Ajin, a detail error stacktrace and the xml+xsd files might helps me to reproduce the error, can you provide it?