Usar la API del catálogo XML | Java
Resuelva referencias de DTD, entidades y URI alternativas en documentos de
origen XML utilizando los diversos tipos de entrada del estándar XML Catalog.
El estándar de catálogo XML define varios tipos de entrada. Entre ellos, las
entradas del sistema, incluyendo las entradas, system,
rewriteSystem y systemSuffix se utilizan para la resolución de
DTD y referencias a entidades en los documentos fuente XML, mientras que las
entradas uri son para las referencias URI alternas.
Referencia del sistema
Utilice un objeto CatalogResolver para localizar un recurso local.
Localización de un recurso local
El siguiente ejemplo demuestra cómo utilizar un objeto
CatalogResolver para localizar un recurso local mediante una entrada
system, dado un archivo XML que contiene una referencia a la propiedad
example.dtd:
<?xml version="1.0"?>
<!DOCTYPE catalogtest PUBLIC "-//OPENJDK//XML CATALOG DTD//1.0"
"http://openjdk.java.net/xml/catalog/dtd/example.dtd">
<catalogtest>
Test &example; entry
</catalogtest>
El example.dtd define una entidad "example":
<!ENTITY example "system">
example.dtdNo es necesario que exista el URI del XML. El propósito es
proporcionar un identificador único para que el objeto
CatalogResolver localice un recurso local. Para hacer esto, cree un
archivo de entrada de catálogo llamado catalog.xml con una entrada system para
hacer referencia al recurso local:
<?xml version="1.0" encoding="UTF-8"?>
<catalog xmlns="urn:oasis:names:tc:entity:xmlns:xml:catalog">
<system
systemId="http://openjdk.java.net/xml/catalog/dtd/example.dtd"
uri="example.dtd"/>
</catalog>
Con este catálogo y la entrada system, todo lo que necesita hacer es obtener
un objeto CatalogFeatures predeterminado y establecer el URI en el archivo de
catálogo para crear un objeto CatalogResolver:
CatalogResolver cr = CatalogManager.catalogResolver(CatalogFeatures.defaults(), catalogUri);
catalogUri debe ser un URI válido. Por ejemplo:
URI.create("file:///users/auser/catalog/catalog.xml")
El objeto CatalogResolver ahora se puede utilizar como un solucionador XML de
JDK. En el siguiente ejemplo, se usa como SAX EntityResolver:
SAXParserFactory factory = SAXParserFactory.newInstance();
factory.setNamespaceAware(true);
XMLReader reader = factory.newSAXParser().getXMLReader();
reader.setEntityResolver(cr);
Observe que en el ejemplo, el identificador del sistema recibe un URI
absoluto. Eso hace que sea fácil para el solucionador encontrar la
coincidencia con exactamente lo mismo systemId en la entrada system del
catálogo.
Si el identificador system en XML es relativo, entonces puede complicar el
proceso de comparación porque el procesador XML puede haberlo hecho absoluto
con un URI base especificado o el URI del archivo fuente. En esa situación, la
entrada systemId del sistema debería coincidir con el URI absoluto anticipado.
Una solución más sencilla es utilizar la entrada systemSuffix, por
ejemplo:
<systemSuffix systemIdSuffix="example.dtd" uri="example.dtd"/>
La entrada systemSuffix coincide con cualquier referencia que termine
en una fuente XML example.dtd y la resuelve en un archivo example.dtd
local como se especifica en el atributo uri. Puede agregar más para
asegurarse de que systemId sea la referencia única o correcta. Por
ejemplo, es posible establecer el systemIdSuffix a
xml/catalog/dtd/example.dtd, o cambiar el nombre id tanto en el archivo de
origen XML y la entrada systemSuffix para que sea un partido único, por
ejemplo my_example.dtd.
El URI de la entrada system puede ser absoluto o relativo. Si los recursos
externos tienen una ubicación fija, es más probable que un URI absoluto
garantice la unicidad. Si los recursos externos se colocan en relación con su
aplicación o el archivo de entrada del catálogo, entonces un URI relativo
puede ser más efectivo, permitiendo la implementación de su aplicación sin
saber dónde está instalada. Dicho URI relativo luego se resuelve usando el URI
base o el URI del archivo de catálogo si no se especifica el URI base. En el
ejemplo anterior, example.dtd se supone que se ha colocado en el mismo
directorio que el archivo de catálogo.
Referencia pública
Utilice una entrada public en lugar de una entrada system para encontrar un
recurso deseado.
Si ninguna entrada system coincide con el recurso deseado y la propiedad
PREFER se especifica para que coincida public, una entrada public puede hacer
lo mismo que una entrada system. Tenga en cuenta que public es la
configuración predeterminada de la propiedad PREFER.
Usando una entrada pública
Cuando la referencia de DTD en el archivo XML analizado contiene un
identificador público como "-//OPENJDK//XML CATALOG DTD//1.0", una entrada
public se puede escribir de la siguiente manera en el archivo de entrada de
catálogo:
<public publicId="-//OPENJDK//XML CATALOG DTD//1.0" uri="example.dtd"/>
Cuando crea y utiliza un objeto CatalogResolver con este archivo de
entrada, el se resuelve example.dtd mediante la propiedad publicId.
Referencia de URI
Utilice una entrada uri para encontrar un recurso deseado.
Las entradas de tipo de URI, incluidas uri, rewriteURI y
uriSuffix, se pueden utilizar de forma similar a las entradas de tipo
de sistema.
Usar entradas de URI
Si bien el estándar del catálogo XML da preferencia a las entradas system de
tipo para resolver referencias DTD y las entradas uri de tipo para todo lo
demás, la API de catálogo XML de Java no hace esa distinción. Esto se debe a
que las especificaciones para los solucionadores XML de Java existentes,
como XMLResolver y LSResourceResolver, no dan preferencia. Las
entradas uri de tipo, incluidas uri, rewriteURI y
uriSuffix, se pueden utilizar de forma similar a las entradas system
de tipo. Los elementos uri se definen para asociar una referencia de URI
alternativa con una referencia de URI. En el caso de referencia system, esta
es la propiedad systemId.
Por lo tanto, puede reemplazar la entrada system con una entrada uri en el
siguiente ejemplo, aunque las entradas system se utilizan más generalmente
para referencias DTD.
<system
systemId="http://openjdk.java.net/xml/catalog/dtd/example.dtd"
uri="example.dtd"/>
Una entrada uri tendría el siguiente aspecto:
<uri name="http://openjdk.java.net/xml/catalog/dtd/example.dtd" uri="example.dtd"/>
Si bien las entradas system se utilizan con frecuencia para DTD, uri se
prefieren las entradas para referencias de URI como la importación e inclusión
de XSD y XSL. El siguiente ejemplo usa una entrada uri para resolver una
importación XSL.
Como se describe en interfaces API de catálogo XML , el API Catálogo XML
define la interfaz CatalogResolver que se extiende Java XML Resolvers
incluyendo EntityResolver, XMLResolver, URIResolver, y LSResolver. Por lo
tanto, un objeto CatalogResolver puede ser utilizado por SAX, DOM, StAX,
Schema Validation, así como XSLT Transform. El siguiente código crea un objeto
CatalogResolver con la configuración de funciones predeterminada:
CatalogResolver cr = CatalogManager.catalogResolver(CatalogFeatures.defaults(), catalogUri);
Luego, el código registra este objeto CatalogResolver en una clase
TransformerFactory donde URIResolver se espera un objeto:
TransformerFactory factory = TransformerFactory.newInstance();
factory.setURIResolver(cr);
Alternativamente, el código puede registrar el objeto
CatalogResolver en el objeto Transformer:
Transformer transformer = factory.newTransformer(xslSource);
transformer.setURIResolver(cur);
Suponiendo que el archivo fuente XSL contiene un elemento import para importar
el archivo xslImport.xsl a la fuente XSL:
<xsl:import href="pathto/xslImport.xsl"/>
Para resolver la referencia import a dónde se encuentra realmente el archivo
de importación, se debe establecer un objeto CatalogResolver en la
clase TransformerFactory antes de crear el objeto Transformer, y se debe
agregar una entrada uri como la siguiente al archivo de entrada de catálogo:
<uri name="pathto/xslImport.xsl" uri="xslImport.xsl"/>
La discusión sobre URIs absolutos o relativos y el uso de entradas
systemSuffix o uriSuffix con la referencia del sistema también
se aplica a las entradas uri.
Comentarios
Publicar un comentario