Validate XML using a XSD (XML Schema)Tag(s): XML
Consider this XML file howto.xml :
<?xml version="1.0" encoding="ISO-8859-1"?>
<howto xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<topic>
<title>Java</title>
<url>http://www.rgagnon.com/topics/java-xml.html</url>
</topic>
<topic>
<title>PowerBuilder</title>
<url>http://www.rgagnon.com/topics/pb-powerscript.htm</url>
</topic>
<topic>
<title>Javascript</title>
<url>http://www.rgagnon.com/topics/js-language.html</url>
</topic>
<topic>
<title>VBScript</title>
<url>http://www.rgagnon.com/topics/wsh-vbs.html</url>
</topic>
</howto>
The external howto.xsd :
<?xml version="1.0" encoding="ISO-8859-1"?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema">
<xs:element name="howto">
<xs:complexType>
<xs:sequence>
<xs:element name="topic" maxOccurs="unbounded">
<xs:complexType>
<xs:sequence>
<xs:element name="title" type="xs:string"/>
<xs:element name="url" type="httpURI"/>
</xs:sequence>
</xs:complexType>
</xs:element>
</xs:sequence>
</xs:complexType>
</xs:element>
<xs:simpleType name="httpURI">
<xs:restriction base="xs:anyURI">
<xs:pattern value="http://.*" />
</xs:restriction>
</xs:simpleType>
</xs:schema>
The code (using SAX parser) to validate an XML file using a given external XSD.
import java.io.IOException;
// SAX
import javax.xml.parsers.SAXParser;
import javax.xml.parsers.SAXParserFactory;
import org.xml.sax.XMLReader;
//SAX and external XSD
import javax.xml.transform.Source;
import javax.xml.transform.stream.StreamSource;
import javax.xml.validation.SchemaFactory;
import javax.xml.parsers.ParserConfigurationException;
import org.xml.sax.ErrorHandler;
import org.xml.sax.SAXException;
import org.xml.sax.SAXParseException;
import org.xml.sax.InputSource;
public class XMLUtils {
private XMLUtils() {}
// validate SAX and external XSD
public static boolean validateWithExtXSDUsingSAX(String xml, String xsd)
throws ParserConfigurationException, IOException
{
try {
SAXParserFactory factory = SAXParserFactory.newInstance();
factory.setValidating(false);
factory.setNamespaceAware(true);
SchemaFactory schemaFactory = SchemaFactory.newInstance("http://www.w3.org/2001/XMLSchema");
SAXParser parser = null;
try {
factory.setSchema(schemaFactory.newSchema(new Source[] {new StreamSource( xsd )}));
parser = factory.newSAXParser();
}
catch (SAXException se) {
System.out.println("SCHEMA : " + se.getMessage()); // problem in the XSD itself
return false;
}
XMLReader reader = parser.getXMLReader();
reader.setErrorHandler(
new ErrorHandler() {
public void warning(SAXParseException e) throws SAXException {
System.out.println("WARNING: " + e.getMessage()); // do nothing
}
public void error(SAXParseException e) throws SAXException {
System.out.println("ERROR : " + e.getMessage());
throw e;
}
public void fatalError(SAXParseException e) throws SAXException {
System.out.println("FATAL : " + e.getMessage());
throw e;
}
}
);
reader.parse(new InputSource(xml));
return true;
}
catch (ParserConfigurationException pce) {
throw pce;
}
catch (IOException io) {
throw io;
}
catch (SAXException se){
return false;
}
}
public static void main (String args[]) throws Exception{
System.out.println
(XMLUtils.validateWithExtXSDUsingSAX
("c:/temp/howto.xml", "c:/temp/howto.xsd"));
/*
output :
true
*/
}
}
The XML can contain a reference to the XSD to be used.
<?xml version="1.0" encoding="ISO-8859-1"?>
<howto xsi:noNamespaceSchemaLocation="howto.xsd"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<topic>
<title>Java</title>
<url>http://www.rgagnon.com/topics/java-xml.html</url>
</topic>
...
</howto>
The code (using DOM parser) to validate an XML file using the referenced XSD :
import java.io.IOException;
// DOM
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;
import org.xml.sax.ErrorHandler;
import org.xml.sax.SAXException;
import org.xml.sax.SAXParseException;
import org.xml.sax.InputSource;
public class XMLUtils {
private XMLUtils() {}
// validate DOM and internal XSD
public static boolean validateWithIntXSDUsingDOM(String xml)
throws ParserConfigurationException, IOException
{
try {
DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
factory.setValidating(true);
factory.setNamespaceAware(true);
factory.setAttribute("http://java.sun.com/xml/jaxp/properties/schemaLanguage",
"http://www.w3.org/2001/XMLSchema");
DocumentBuilder builder = factory.newDocumentBuilder();
builder.setErrorHandler(
new ErrorHandler() {
public void warning(SAXParseException e) throws SAXException {
System.out.println("WARNING: " + e.getMessage()); // do nothing
}
public void error(SAXParseException e) throws SAXException {
System.out.println("ERROR: " + e.getMessage());
throw e;
}
public void fatalError(SAXParseException e) throws SAXException {
System.out.println("FATAL: " + e.getMessage());
throw e;
}
}
);
builder.parse(new InputSource(xml));
return true;
}
catch (ParserConfigurationException pce) {
throw pce;
}
catch (IOException io) {
throw io;
}
catch (SAXException se){
return false;
}
}
public static void main (String args[]) throws Exception{
System.out.println
(XMLUtils.validateWithIntXSDUsingDOM
("c:/temp/howto.xml"));
}
}
The code (using SAX parser) to validate an XML file using the referenced XSD :
import java.io.IOException;
// SAX
import javax.xml.parsers.SAXParser;
import javax.xml.parsers.SAXParserFactory;
import org.xml.sax.XMLReader;
import javax.xml.parsers.ParserConfigurationException;
import org.xml.sax.ErrorHandler;
import org.xml.sax.SAXException;
import org.xml.sax.SAXParseException;
import org.xml.sax.InputSource;
public class XMLUtils {
private XMLUtils() {}
// validate SAX and internal XSD
public static boolean validateWithIntXSDWithSAX(String xml)
throws ParserConfigurationException, IOException
{
try {
SAXParserFactory factory = SAXParserFactory.newInstance();
factory.setValidating(true);
factory.setNamespaceAware(true);
SAXParser parser = factory.newSAXParser();
parser.setProperty("http://java.sun.com/xml/jaxp/properties/schemaLanguage",
"http://www.w3.org/2001/XMLSchema");
XMLReader reader = parser.getXMLReader();
reader.setErrorHandler(
new ErrorHandler() {
public void warning(SAXParseException e) throws SAXException {
System.out.println("WARNING: " + e.getMessage()); // do nothing
}
public void error(SAXParseException e) throws SAXException {
System.out.println("ERROR: " + e.getMessage());
throw e;
}
public void fatalError(SAXParseException e) throws SAXException {
System.out.println("FATAL: " + e.getMessage());
throw e;
}
}
);
reader.parse(new InputSource(xml));
return true;
}
catch (ParserConfigurationException pce) {
throw pce;
}
catch (IOException io) {
throw io;
}
catch (SAXException se){
return false;
}
}
public static void main (String args[]) throws Exception{
System.out.println(XMLUtils.validateWithIntXSDWithSAX("c:/temp/howto.xml"));
}
}
This HowTo uses the built-in XML parser, you can switch JAXP in debug mode by passing a special switch on the JVM command-line.
java -Djaxp.debug=1 ... or java -Djaxp.debug ...
JAXP: found null in $java.home/jaxp.properties JAXP: no META-INF/services/javax.xml.validation.SchemaFactory file was found JAXP: attempting to use the platform default XML Schema validator JAXP: createInstance(com.sun.org.apache.xerces.internal.jaxp.validation.XMLSchemaFactory) ...
NOTES :
mail_outline
Send comment, question or suggestion to howto@rgagnon.com
Send comment, question or suggestion to howto@rgagnon.com