Usar EntityResolver y DTDHandler
EntityResolver. El DTDHandler se invoca cuando
el DTD encuentra una entidad no
analizada o una declaración de
notación. El
EntityResolver entra en juego cuando debe resolverse una
URN (ID pública) a una
URL (ID de Sistema).
El API DTDHandler
En la sección Referenciar Entidades Binarias
vimos un método para referenciar un fichero que contiene datos binarios, como un fichero de
imagen, usando tipos de datos MIME. Este es el mecanismo extensible más simple de usar.
Por compatibilidad con viejos datos al estilo
SGML, también es posible definir una
entidad no analizada.
La palabra clave NDATA define una entidad de este tipo:
<!ENTITY myEntity SYSTEM "..URL.." NDATA gif>
El NDATA dice que los datos de esta unidad no son datos XML
analizables, pero en su lugar son datos que usan otro tipo de
notación. En este caso,
la notación se llama "gif". El DTD debe entonces incluir una declaración
para esta notación, que se parecería algo a esto:
<!NOTATION gif SYSTEM "..URL..">
Cuando el analizador ve una entidad sin analizar o una declaración de notación, no
hace nada con la información excepto pasarla a la otra aplicación usando el
interface DTDHandler. Este interface define dos métodos:
notationDecl(String name, String publicId, String systemId)
unparsedEntityDecl(String name, String publicId, String systemId,
String notationName)
Al método notationDecl se le pasa el nombre de la notación y
el identificador público o del sistema, o ámbos, dependiendo de lo que se haya
declarado en el DTD. Al método unparsedEntityDecl se le pasa
el nombre de la entidad, los identificadores apropiados, y el nombre de la notación que usa.
|
Nota:
El interface DTDHandlet está implementado por la clase Java XML:
com.sun.xml.parser.DtdEventListener
|
Las notaciones también pueden usarse en declaraciones de atributos. Por ejemplo,
la siguiente declaración requiere notaciones para los formatos de ficheros de
imagen GIF y PNG:
<!ENTITY image EMPTY>
<!ATTLIST image
...
type NOTATION (gif | png) "gif"
>
Aquí, se declara el tipo como gif, o png.
Por defecto, si ninguno se especifica, es gif.
Si la notación se usa para describir una entidad sin analizar o un atributo, es
enviada a la aplicación para hacer el procesamiento adecuado. El analizador no
conoce nada sobre la semántica de las notaciones. Sólo las pasa sobre las declaraciones.
El API EnityResolver
El API EntityResolver nos permite convertir una ID pública
(URN) en una ID del sistema
(URL). Nuestra aplicación
podría necesitar hacer esto, por ejemplo, para convertir algo como
href="urn:/someName" en
"http://someURL".
El interface EntityResolver define un sólo método:
resolveEntity(String publicId, String systemId)
Este método devuelve un objeto InputSource, que puede ser
usado para acceder a contenidos de entidades. Convertir una URL en un
InputSource es muy sencillo. Pero la URL que es pasada
como el ID del sistema será la localización del documento original que es, como no,
algún lugar en la Web. Para acceder a una copia local, si existe, debemos mantener
un catálogo en algún lugar en el sistema que mapea nombres (IDs públicas) en URLs
locales.
La clase Java XML com.sun.xml.parser.Resolver ha sido
diseñada para este propósito. Creamos un ejemplar de
Resolver y llamamos a su método
registerCatalogEntry para asociar una URL con una URN.
Luego usamos el método setEntityResolver del analizador
SAX para configurar el analizador con nuestro ejemplar
Resolver, lo que permite usar una versión local del
recurso en lugar de un acceso a la Web siempre que la ID pública corresponda con la
que se ha requerido.