Funciona igual que el analizador con DTD. Las diferencias vienen por dos aspectos: primero, a la hora de configurar el 'parser' tenemos que especificar que vamos a usar validación por esquema XML y, en segundo lugar, en el documento XML debemos hacer referencia al Esquema. Empezamos por la configuración del analizador:
//// Análisis
SAXParser parser= factoria.newSAXParser();
Manejador man = new Manejador();
//// El lector valida de acuerdo al esquema
XMLReader xmlReader = parser.getXMLReader();
xmlReader.setFeature("http://apache.org/xml/features/validation/schema",true);
parser.parse( fich, man ); // Parser del fichero 'fich' con el manejador 'man'
El analizador muestra el valor de las las etiquetas 'titulo' y 'autor'. En este ejemplo hacemos una mejora sobre el ejemplo anterior: sólo mostramos el valor (characters) de una etiqueta si es 'libro' o 'autor'
import org.xml.sax.*;
import org.xml.sax.helpers.DefaultHandler;
/***************************************************************************
* Manejador de eventos SAX
***************************************************************************/
public class Manejador extends DefaultHandler {
private boolean esTitulo = false;
private boolean esAutor = false;
....
public void startElement(String espacioNombres, String nomLocal, String nomCompleto, Attributes atrs) {
System.out.println("Nombre local:" + nomLocal );
for ( int i = 0; i < atrs.getLength(); i++) {
System.out.println(" ATRIB. Nombre local: " + atrs.getLocalName(i) );
System.out.println(" ATRIB. Tipo: " + atrs.getType(i) );
System.out.println(" ATRIB. Valor: " + atrs.getValue(i) );
}
if (nomLocal.equalsIgnoreCase("titulo"))
esTitulo = true;
if (nomLocal.equalsIgnoreCase("autor"))
esAutor = true;
}
public void endElement(String espacio, String nomLocal, String nomCompleto) {
}
public void characters(char[] ch, int inicio, int longitud) {
if ( esTitulo || esAutor ) {
String cad = new String( ch, inicio, longitud);
System.out.println(" Caracteres:" + cad );
System.out.println(" Inicio:" + inicio + " Longitud:" + longitud );
esTitulo = false;
esAutor = false;
}
}
....
}
En este pequeño ejemplo se ve la ventaja e inconveniente de SAX: es sencillo, pero no se escala de forma fácil, es decir, hay que controlar etiqueta a etiqueta. En nuestro ejemplo sólo tenemos 2, pero imaginemos que tuviesemos 15.
El Esquema (libreria3.xsd) no tiene ninguna particularidad. Señala que 'libros' es una secuencia del tipo 'libro'; a su vez, un libro es una secuencia de 'titulo' y 'autor':
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema">
<xs:element name="libro">
<xs:complexType>
<xs:sequence>
<xs:element name="titulo" type="xs:token"/>
<xs:element name="autor" type="xs:token"/>
</xs:sequence>
</xs:complexType>
</xs:element>
<xs:element name="libros" >
<xs:complexType>
<xs:sequence>
<xs:element ref="libro" maxOccurs="unbounded" />
</xs:sequence>
</xs:complexType>
</xs:element>
</xs:schema>
El archivo XML hace referencia al Esquema (por sencillez usamos 'file' en vez de 'http'):
<?xml version="1.0" encoding="ISO-8859-1"?>
<libros xmlns:xsi='http://www.w3.org/2001/XMLSchema-instance'
xsi:noNamespaceSchemaLocation="file:C:/DOC/Java_eclipse/docenBasico/src/xmlSAX02/libreria3.xsd"
xsi:schemaLocation="file:C:/DOC/Java_eclipse/docenBasico/src/xmlSAX02/libreria3.xsd
file:C:/DOC/Java_eclipse/docenBasico/src/xmlSAX02/libreria3.xsd">
<libro>
<titulo>El fin de una odisea</titulo>
<autor>Pedro Gomez</autor>
</libro>
<libro>
<titulo>Un lugar en la mente de mi gato</titulo>
<autor>Anónimo</autor>
</libro>
</libros>
El directorio actual es C:\DOC\Java_eclipse\docenBasico
Trato de abrir el archivo C:\DOC\Java_eclipse\docenBasico/src/xmlSAX02/libreria3.xml
Se ha abierto el archivo. Inicio del análisis
Nombre local:libros
ATRIB. Nombre local: noNamespaceSchemaLocation
ATRIB. Tipo: CDATA
ATRIB. Valor: file:C:/DOC/Java_eclipse/docenBasico/src/xmlSAX02/libreria3.xsd
ATRIB. Nombre local: schemaLocation
ATRIB. Tipo: CDATA
ATRIB. Valor: file:C:/DOC/Java_eclipse/docenBasico/src/xmlSAX02/libreria3.xsd file:C:/DOC/Java_eclipse/docenBasico/src/xmlSAX02/libreria3.xsd
Nombre local:libro
Nombre local:titulo
Caracteres:El fin de una odisea
Inicio:1 Longitud:20
Nombre local:autor
Caracteres:Pedro Gomez
Inicio:1 Longitud:11
Nombre local:libro
Nombre local:titulo
Caracteres:Un lugar en la mente de mi gato
Inicio:1 Longitud:31
Nombre local:autor
Caracteres:Anónimo
Inicio:1 Longitud:7
Fin del análisis.