Les objets implémentant l'interface Locator sont capables de fournir des informations sur la localisation du dernier événement produit au sein d'un document XML.
Les informations sont des numéros de ligne et de colonne, ainsi que les identificateurs SYSTEM et PUBLIC du document courant.
L'encodage de caractères et le numéro de version XML de l'entité situé à l'emplacement courant, peuvent être obtenus si l'objet implémente l'interface Locator2. Cela se vérifie en invoquant la méthode getFeature() d'une fabrique SAXParserFactory, qui retourne true si l'es objets de localisation implémente l'interface Locator2.
SAXParserFactory fabrique = SAXParserFactory.newInstance(); if(fabrique.getFeature("use-locator2")) System.out.println("L'implémentation supporte Locator2");
SAX possède une classe abstraite dénommée DefaultHandler dans laquelle existe une méthode dont la fonction est de recevoir un objet Locator. Il s'agît de la méthode setDocumentLocator() qui reçoit lors de l'analyse SAX, un argument de type Locator qui peut être exploité si cette méthode a été implémentée.
import javax.xml.parsers.SAXParser; import javax.xml.parsers.SAXParserFactory; import org.xml.sax.Attributes; import org.xml.sax.Locator; import org.xml.sax.helpers.DefaultHandler; import java.io.File; public class GestionEmplacement extends DefaultHandler { public static void main(String[] args) throws Exception { SAXParserFactory fabrique = SAXParserFactory.newInstance(); SAXParser analyseur = fabrique.newSAXParser(); analyseur.parse(new File("logitheque.xml"), new GestionEmplacement()); } private Locator emplacement; public void setDocumentLocator(Locator locator) { this.emplacement = locator; } public void startElement( String uri, String localName, String qName, Attributes attributes) { if (this.emplacement == null) System.err.println("L'objet Locator n'est pas disponible ! "); else { System.out.println("ELEMENT : " + qName); System.out.println("Numéro de ligne : " + this.emplacement.getLineNumber()); System.out.println("Numéro de colonne : " + this.emplacement.getColumnNumber()); System.out.println("ID Système : " + this.emplacement.getSystemId()); System.out.println("ID Public : " + this.emplacement.getPublicId()); } } }
Il est possible d'implémenter l'interface ContentHandler qui déclare la méthode setDocumentLocator(). La classe abstraite DefaultHandler implémente cette interface.
import org.xml.sax.Attributes; import org.xml.sax.Locator; import org.xml.sax.ContentHandler; public class GestionEmplacement implements ContentHandler { private Locator emplacement; public void setDocumentLocator(Locator locator) { this.emplacement = locator; } public void startElement( String uri, String localName, String qName, Attributes attributes) { if (this.emplacement == null) System.err.println("L'objet Locator n'est pas disponible ! "); else { System.out.println("ELEMENT : " + qName); System.out.println("Numéro de ligne : " + this.emplacement.getLineNumber()); System.out.println("Numéro de colonne : " + this.emplacement.getColumnNumber()); } } }
DOM comporte une interface DOMLocator située dans le paquetage javax.xml.transform.dom. Cette interface contient une seule méthode (getOriginatingNode()) retournant le noeud à l'origine de l'événement courant.
L'interface DOMLocator étend une autre interface SourceLocator, laquelle dispose de méthodes délivrant les mêmes informations que le localisateur SAX, soit des numéros de ligne et de colonne, ainsi que les identificateurs SYSTEM et PUBLIC du document courant.
L'objet implémentant l'interface SourceLocator s'obtient à partir des exceptions TransformerException et TransformerConfigurationException du paquetage javax.xml.transform.
public class TransformerException extends Exception { SourceLocator locator; //... public String getMessageAndLocation() { StringBuffer sbuffer = new StringBuffer(); String message = super.getMessage(); if (null != message) { sbuffer.append(message); } if (null != locator) { String systemID = locator.getSystemId(); int line = locator.getLineNumber(); int column = locator.getColumnNumber(); if (null != systemID) { sbuffer.append("; SystemID: "); sbuffer.append(systemID); } if (0 != line) { sbuffer.append("; Line#: "); sbuffer.append(line); } if (0 != column) { sbuffer.append("; Column#: "); sbuffer.append(column); } } return sbuffer.toString(); } //... }
Xerces 2 propose une implémentation de l'interface DOMLocator, en l'occurrence org.apache.xerces.dom.DOMLocatorImpl. La classe org.apache.xerces.dom.DOMNormalizer déclare un champ protégé fLocator utilisé par plusieurs méthodes de cette classe pour vérifier si les valeurs d'attributs (isAttrValueWF()), les sections CDATA (isCDataWF()), les commentaires (isCommentWF()) et des caractères XML (isXMLCharWF()), sont bien formés. Les objets DOMLocatorImpl sont souvent utilisés pour rapporter une erreur.