Suite à la création de l'objet DocumentBuilderFactory, il est possible de déclarer avec quel moyen (DTD ou schéma) sera validé le document XML.
Une solution consiste à passer par la méthode setAttribute() de la fabrique. Celle-ci accepte dans ce cas deux arguments.
Le premier est une chaîne de caractères exprimant une propriété indiquant le type de la valeur passée à la méthode setAttribute(). Il existe deux possibilités :
fabrique.setAttribute( "http://java.sun.com/xml/jaxp/properties/schemaLanguage", "http://www.w3.org/2001/XMLSchema"); fabrique.setAttribute( "http://java.sun.com/xml/jaxp/properties/schemaSource" new File("schema.xsd"));
Le second argument de la méthode setAttribute() indique :
Pour des raisons de commodité, il peut être utile de placer les identificateurs de propriétés au sein de constantes.
public static final String JAXP_SCHEMA_LANGUAGE = "http://java.sun.com/xml/jaxp/properties/schemaLanguage"; public static final String JAXP_SCHEMA_SOURCE = "http://java.sun.com/xml/jaxp/properties/schemaSource";
Le langage de schéma est disponible sous la forme d'une constante dans la classe javax.xml.XMLConstants.
fabrique.setAttribute( JAXP_SCHEMA_LANGUAGE, XMLConstants.W3C_XML_SCHEMA_NS_URI);
Si l'implémentation sous-jacente gère d'autres langages de schéma, à l'image de Relax NG. Il est possible de spécifier l'adresse URI de ce langage.
fabrique.setAttribute( JAXP_SCHEMA_LANGUAGE, XMLConstants.RELAXNG_NS_URI);
Si le document XML nécessite plusieurs schémas XML pour sa validation, il faut créer un tableau et y placer les références vers les schémas.
String schemaSociete = "societe.xsd"; String schemaService = "service.xsd"; String schemaEmploye = "employe.xsd"; String[] schemas = { schemaSociete, schemaService, schemaEmploye, }; DocumentBuilderFactory fabrique = DocumentBuilderFactory.newInstance() fabrique.setAttribute(JAXP_SCHEMA_SOURCE, schemas);
La valeur à soumettre à la méthode setAttribute(JAXP_SCHEMA_SOURCE, valeur) peut être de différents types :
La soumission d'une source validante impose l'analyseur de valider le document XML avec elle. Si le document XML possède une référence vers un schéma XML, alors ce dernier sera purement et simplement ignoré. Par contre, si aucune source validante n'est fournie au moyen de la méthode setAttribute(), le schéma présent dans le document XML sera retenu pour la validation.
fabrique.setAttribute( JAXP_SCHEMA_LANGUAGE, XMLConstants.W3C_XML_SCHEMA_NS_URI); //fabrique.setAttribute(JAXP_SCHEMA_SOURCE, new File(sourceXSD));
La prise en compte des espaces de noms et le processus de validation doivent être activés,
fabrique.setNamespaceAware(true); fabrique.setValidating(true);
L'invocation de la méthode setValidating(true) entraîne la validation du document XML par rapport à l'éventuelle définition de type de document (DTD) déclarée par <!DOCTYPE...>, si aucune information supplémentaire de validation n'est précisée dans l'application.
import java.io.IOException; import javax.xml.parsers.XMLConstants; import javax.xml.parsers.DocumentBuilder; import javax.xml.parsers.DocumentBuilderFactory; import javax.xml.parsers.ParserConfigurationException; import org.w3c.dom.Document; import org.w3c.dom.Element; import org.xml.sax.SAXException; public class ValidationXML { public static final String JAXP_SCHEMA_LANGUAGE = "http://java.sun.com/xml/jaxp/properties/schemaLanguage"; public static final String JAXP_SCHEMA_SOURCE = "http://java.sun.com/xml/jaxp/properties/schemaSource"; public static final void main(String[] args) { ValidationXML oValid = new ValidationXML( "fichier.xml", "fichier.xsd"); } public ValidationXML(String fichierXML, Object sourceXSD) { try { DocumentBuilderFactory fabrique = DocumentBuilderFactory.newInstance(); fabrique.setNamespaceAware(true); fabrique.setValidating(true); fabrique.setAttribute( JAXP_SCHEMA_LANGUAGE, XMLConstants.W3C_XML_SCHEMA_NS_URI); fabrique.setAttribute(JAXP_SCHEMA_SOURCE, new File(sourceXSD)); DocumentBuilder constructeur = fabrique.newDocumentBuilder(); constructeur.setErrorHandler(new GestionnaireErreurs()); Document document = constructeur.parse(fichierXML); Element racine = document.getDocumentElement(); } catch(Exception e){ e.printStackTrace(); } } } import org.xml.sax.ErrorHandler; import org.xml.sax.SAXParseException; public class GestionnaireErreurs implements ErrorHandler { public void error(SAXParseException e) { System.err.println("ERREUR SAX : " + e.getMessage()); } public void fatalError(SAXParseException e) { System.err.println("ERREUR FATALE SAX : " + e.getMessage()); } public void warning(SAXParseException e) { System.err.println("AVERTISSEMENT SAX : " + e.getMessage()); } }
L'implémentation Xerces offre un autre moyen d'indiquer à l'analyseur DOM ou SAX de valider un document XML.
La caractéristique validation doit être fixée à true afin de contraindre l'analyseur XML à accomplir l'opération de validation.
analyseur.setFeature( "http://xml.org/sax/features/validation", true);
Sans autres informations supplémentaires, l'analyseur XML recherchera l'éventuelle DTD et validera le document XML. Si le document ne contient pas de DTD, la validation échouera.
La validation par un schéma XML doit être spécifiée en paramétrant la caractéristique validation/schema à true.
parser.setFeature( "http://apache.org/xml/features/validation/schema", true);
Une autre caractéristique active la vérification des contraintes gramaticales.
parser.setFeature( "http://apache.org/xml/features/validation/schema-full-checking", true);
Enfin, il ne reste plus qu'à fournir la source validante sous la forme d'une adresse URL. Si le document XML comporte des espaces de noms nécessaires à sa validation, il faut utiliser la la propriété schema/external-schemaLocation, dans le cas contraire schema/external-noNamespaceSchemaLocation conviendra tout à fait. Ces propriétés sont fixées à l'aide de la méthode setProperty().
parser.setProperty( "http://apache.org/xml/properties/schema/external-schemaLocation", schema); parser.setProperty( "http://apache.org/xml/properties/schema/external-noNamespaceSchemaLocation", SchemaUrl);