La validation par un schéma XML est assurée par le paquetage javax.xml.validation. La classe Schema représente un schéma XML écrit dans le langage W3C XML Schema, Relax NG ou autre.
Une instance de la classe Schema s'obtient par la fabrique SchemaFactory, laquelle compile une ressource XML exprimant le schéma W3C ou Relax NG par le biais d'une constante passée lors de l'instanciation de la fabrique.
SchemaFactory fabriqueW3C = SchemaFactory.newInstance( XMLConstants.W3C_XML_SCHEMA_NS_URI); SchemaFactory fabriqueRNG = SchemaFactory.newInstance( XMLConstants.RELAXNG_NS_URI); Source sourceW3C = new StreamSource(new File("c:\\employes.xsd")); Source sourceRNG = new StreamSource(new File("c:\\employes.rng")); Schema schemaW3C = fabrique.newSchema(sourceW3C); Schema schemaRNG = fabrique.newSchema(sourceRNG);
Un objet Schema peut être consitué à partir de diverses sources d'entrée, comme un flux (StreamSource), une source DOM (DOMSource) ou SAX (SAXSource), un fichier et une adresse URL. Il est même possible de passer un tableau de sources (Source[]) dans le cas où plusieurs schémas XML seraient nécessaires pour valider un document.
Document docXSD = parser.parse(new File("C:\\schema.xsd")); Source sourceXSD = new DOMSource(docXSD); Schema schemaW3C = fabrique.newSchema(sourceXSD);
Désormais, la classe Validator doit être instanciée par la méthode newValidator() de l'objet Schema. Puis à partir du validateur ainsi récupéré, l'invocation de sa méthode validate() provoque la validation du document XML par rapport à un schéma XML.
import javax.xml.XMLConstants; import javax.xml.parsers.DocumentBuilder; import javax.xml.parsers.DocumentBuilderFactory; import javax.xml.parsers.ParserConfigurationException; import javax.xml.transform.Source; import javax.xml.transform.dom.DOMSource; import javax.xml.transform.sax.SAXSource; import javax.xml.transform.stream.StreamSource; import javax.xml.validation.Schema; import javax.xml.validation.SchemaFactory; import javax.xml.validation.Validator; import org.xml.sax.InputSource; import org.xml.sax.SAXException; import org.w3c.dom.Document; import java.io.File; import java.io.IOException; public class Validation { public static void main(String[] args) { try { DocumentBuilderFactory fabriqueAnalyseur = DocumentBuilderFactory.newInstance(); DocumentBuilder analyseur = fabriqueAnalyseur.newDocumentBuilder(); Document document = analyseur.parse(new File("C:\\employes.xml")); SchemaFactory fabrique = SchemaFactory.newInstance( XMLConstants.W3C_XML_SCHEMA_NS_URI); fabrique.setErrorHandler(new GestionnaireErreurs()); InputSource sourceentree = new InputSource("C:\\employes.xsd"); SAXSource sourceXSD = new SAXSource(sourceEntree); Schema schema = fabrique.newSchema(sourceXSD); Validator validateur = schema.newValidator(); validateur.validate(new DOMSource(document)); } catch (SAXException e) { e.printStackTrace(); } catch (ParserConfigurationException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } } } /Gestionaire d'erreurs import org.xml.sax.ErrorHandler; import org.xml.sax.SAXException; import org.xml.sax.SAXParseException; class GestionnaireErreurs implements ErrorHandler { public void fatalError( SAXParseException e ) throws SAXException { System.out.println("ERREUR FATALE"); e.printStackTrace(); } public void error( SAXParseException e ) throws SAXException { System.out.println("ERREUR"); e.printStackTrace(); } public void warning( SAXParseException e ) throws SAXException { System.out.println("AVERTISSEMENT"); e.printStackTrace(); } }
Le gestionnaire d'erreurs permet de rapporter les erreurs lancées durant le processus de validation.
Si le schéma n'est pas rédigé dans le langage de schéma correspondant à l'URI d'espace de noms, plusieurs erreurs peuvent être lancées simultanément.
org.xml.sax.SAXParseException: s4s-elt-schema-ns: The namespace of element 'element' must be from the schema namespace, 'http://www.w3.org/2001/XMLSchema'. org.xml.sax.SAXParseException: s4s-att-not-allowed: Attribute 'datatypeLibrary' cannot appear in element 'element'.ERREUR
Si le schéma est écrit dans un langage qui n'est pas supporté par l'analyseur JAXP, une exception IllegalArgumentException se produit sur l'instruction de création d'un objet SchemaFactory.
Exception in thread "main" java.lang.IllegalArgumentException: http://purl.oclc.org/dsdl/schematron
La version JDK 1.5 est susceptible de supporter plusieurs langages de schéma, tels que W3C XML Schema, Relax NG ou Schematron. Toutefois, la rise en compte de ces langages de schéma dépend des implémentations d'analyseur. La méthode d'instance isSchemaLanguageSupported() de la classe SchemaFactory peut aider à déterminer si l'implémentation sous-jacente supporte des langages de schéma supplémentatires.
SchemaFactory fabrique = SchemaFactory.newInstance( XMLConstants.W3C_XML_SCHEMA_NS_URI); if(fabrique.isSchemaLanguageSupported( XMLConstants.RELAXNG_NS_URI)) System.out.println("Relax NG est supporté..."); if(fabrique.isSchemaLanguageSupported( "http://purl.oclc.org/dsdl/schematron")) System.out.println("Schematron est supporté...");
Si le choix de valider un document par un schéma XML, il ne faut pas fixer la valeur de la caractéristique de validation (http://xml.org/sax/features/validation) à false.
analyseur.setFeature("http://xml.org/sax/features/validation", false);
Dans le cas contraire, il y aurait une redondance de validation par DTD puis par schéma, et dans le pire des cas, des erreurs pourraient se produire si le document XML ne comporte pas de définition de type de document.