XML schema validation with Dom4j
Hi folks, today I´m feeling geeky!!
First and foremost, if you don´t know what and XML schemas or XML documents are, you´d better listen to my music clicking on the youtube video on your right. For the rest of you, a bit obvious, Dom4j is a Java API, so........
Ok, let´s get started.
Dom4j is a Java API that makes XML manipulation sweet, and easier than with pure DOM or SAX. Besides it let you use XPATH to travers XML documents. Dom4j includes its own XML parser, but this in not able to validate document agains schemas. For that purpose we will use Xerces.
In order to develop our example we will define a very little schema and and two XML documents usign that schema, one will be valid, and the other won´t.
I´m using Java 5, and ignore if this would work with Java 1.4, let me know if you discover something. I will assume you have downloaded the following APIs:
First and foremost, if you don´t know what and XML schemas or XML documents are, you´d better listen to my music clicking on the youtube video on your right. For the rest of you, a bit obvious, Dom4j is a Java API, so........
Ok, let´s get started.
Dom4j is a Java API that makes XML manipulation sweet, and easier than with pure DOM or SAX. Besides it let you use XPATH to travers XML documents. Dom4j includes its own XML parser, but this in not able to validate document agains schemas. For that purpose we will use Xerces.
In order to develop our example we will define a very little schema and and two XML documents usign that schema, one will be valid, and the other won´t.
I´m using Java 5, and ignore if this would work with Java 1.4, let me know if you discover something. I will assume you have downloaded the following APIs:
- Latest dom4j (1.6.1 at the time or writting this).
- Latest Xerces (1.4.4 at the time of writting this).
I´ll use Eclipse througout the whole example, so let´s kick off:
- Create a Java project. Call it XmlValidation
- Add the following libraries to the buid path (Project -> Properties -> Java Build Path -> Libraries -> Add external jars)
- dom4j-1.6.1.jar
- xerces.jar
- Add an XML schema called SongSchema.xsd:
<?xml version="1.0" encoding="UTF-8"?>
<xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema"
targetNamespace="SongSchema" xmlns:album="SongSchema"
elementFormDefault="qualified">
<xsd:element name="album">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="song" type="album:song" />
<xsd:element name="comment" type="xsd:string" />
</xsd:sequence>
</xsd:complexType>
</xsd:element>
<xsd:complexType name="song">
<xsd:sequence>
<xsd:element name="title" type="album:nonemptystring" />
<xsd:element name="author" type="album:nonemptystring" />
<xsd:element name="minutes" type="album:time" />
<xsd:element name="seconds" type="album:time" />
</xsd:sequence>
</xsd:complexType>
<xsd:simpleType name="time">
<xsd:restriction base="xsd:positiveInteger">
<xsd:pattern value='[0-6]?[0-9]'/>
</xsd:restriction>
</xsd:simpleType>
<xsd:simpleType name="nonemptystring">
<xsd:restriction base="xsd:string">
<xsd:pattern value="[\w\W]+"></xsd:pattern>
</xsd:restriction>
</xsd:simpleType>
</xsd:schema>
- Now we create our actual XML file, called MySongs.xml:
<?xml version="1.0" encoding="UTF-8"?>
<album xmlns="SongSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="SongSchema SongSchema.xsd">
<song>
<title>Oceano de sal</title>
<author>Julio Delgado</author>
<minutes>39</minutes>
<seconds>7</seconds>
</song>
<comment>Very Good Song,ideed.</comment>
</album>
- We are nearly there!!!
- Create the validator class, called Validator, in the Validator.java file:
package com.julio.xml;
import java.io.File;
// dom4j import
import org.dom4j.Document;
import org.dom4j.DocumentException;
import org.dom4j.io.SAXReader;
import org.xml.sax.ErrorHandler;
import org.xml.sax.SAXException;
import org.xml.sax.SAXParseException;
public class Validator {
private File file;
private Document doc;
private SAXReader reader;
private handler h;
public Validator(){
reader = new SAXReader(true);
h = new handler();
// Lets configure the reader for full validation
// set the validation feature to true to report validation errors
try {
reader.setFeature("http://xml.org/sax/features/validation", true);
// set the validation/schema feature to true to report validation errors against a schema
reader.setFeature("http://apache.org/xml/features/validation/schema", true);
// set the validation/schema-full-checking feature to true to enable full schema, grammar-constraint checking
reader.setFeature("http://apache.org/xml/features/validation/schema-full-checking", true);
reader.setFeature("http://apache.org/xml/features/continue-after-fatal-error", true);
//reader.setFeature("http://apache.org/xml/features/validation-error-as-fatal", true);
reader.setErrorHandler(h);
} catch (SAXException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
};
public Validator(String fileName)
{
this();
file = new File(fileName);
try {
doc = reader.read(file);
} catch (DocumentException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
// If everything went fine up to this point, now we have
// an XML document in memory and can try to validate.
}
public void setFile(File file) {
this.file = file;
}
public boolean validateXml(){
try {
h.setHasErrors(false);
doc = reader.read(file);
} catch (DocumentException e) {
// TODO Auto-generated catch block
System.out.println(e.getMessage());
//e.printStackTrace();
return false;
}
return !h.getHasErrors();
}
class handler implements ErrorHandler{
private boolean hasErrors;
public handler()
{
hasErrors = false;
}
public boolean getHasErrors()
{
return hasErrors;
}
public void setHasErrors(boolean b)
{
this.hasErrors = b;
}
@Override
public void error(SAXParseException exception) throws SAXException {
System.out.println("Line: " + exception.getLineNumber() + ") " +
exception.getMessage());
hasErrors = true;
}
@Override
public void fatalError(SAXParseException exception) throws SAXException {
// TODO Auto-generated method stub
}
@Override
public void warning(SAXParseException exception) throws SAXException {
// TODO Auto-generated method stub
}
}
}
This code is doing 2 main things:
- Configure the parser in the Validator constructor. This include it´s behavior and a class to handle errors and warnings during parsing.
- Define a class to handle errors. This is needed because otherwise the applicacion would rise and exception with the first error found, and we couldn´t get a list of all the errors present on the Xml file.
- Finally the class that nails everything together, XmlTest, in the file XmlTest.java:
package com.julio.test;
import java.io.File;
import org.dom4j.Document;
import org.dom4j.DocumentException;
import org.dom4j.io.SAXReader;
public class XmlTest {
// Entry point
public static void main(String args[])
{
System.out.println("XmlTest.main()");
XmlTest test = new XmlTest();
test.printWellcomeScreen();
SAXReader reader = new SAXReader();
Document doc = null;
try {
doc = reader.read(new File("xml/Program.xml"));
} catch (DocumentException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
if(doc != null)
{
System.out.println(doc.toString());
if(doc.getRootElement().getName() == "program")
{
System.out.println("program\n");
System.out.println(doc.getRootElement().attributeValue("buid"));
}
}
}
private void printWellcomeScreen()
{
System.out.println("WELLCOME!!!\n");
}
}
- Now just compile and execute. Try different values in the Xml file, and you´ll see how well the validation works.
Enjoy!!!!
0 Comentarios:
Post a Comment
<< Home