Relación del procesador con la API de Java API para el proceso de XML (JAXP)
En la mayoría de casos, tendrá que migrar alguna de las aplicaciones que han utilizado la API de Java™ para el proceso de XML (JAXP) para emplear la API actual.
Las partes de proceso de XSLT y XPath de JAXP se definen haciendo referencia XSLT 1.0 y XPath 1.0. JAXP no tiene ninguna provisión para el proceso de XSLT 2.0 y XPath 2.0. En particular, hay situaciones en que un procesador de XSLT 2.0 o XPath 2.0 debe generar un resultado que sea distinto del que ha generado un procesador XSLT 1.0 o XPath 1.0 ofreciendo una expresión u hoja de estilo idéntica o una entrada idéntica. Además, no es posible instancias el procesador actual utilizado JAXP.
JAXP tampoco da soporte a secuencias, XQuery 1.0, o a muchos de los tipos de datos actuales que están disponibles en XSLT 2.0, XPath 2.0 y XQuery 1.0. JAXP también tiene limitaciones en cuanto a las formas que pueden tener las entradas y salidas. Todo ello le confiere un ajuste reducido para procesar hojas de estilo XSLT 2.0 así como expresiones XPath 2.0 y XQuery 1.0.
En los ejemplos siguientes se muestran los casos de ejemplo de migración común y cómo escribir código utilizando la API actual que equivale al código que podría haber escrito utilizando JAXP.
Proceso de una hoja de estilo XSLT utilizando la API
XFactory factory = XFactory.newInstance();
XSLTExecutable style = factory.prepareXSLT(new StreamSource("style.xsl"));
style.execute(new StreamSource("input.xml"), new StreamResult(System.out));
Proceso de una expresión XPath utilizando la API
XFactory factory = XFactory.newInstance();
XPathExecutable pathExpr = factory.prepareXPath("/doc/child[@id='N1378']");
// Process input from a StreamSource
XSequenceCursor result1 = pathExpr.execute(new StreamSource("input.xml"));
// Process input from a DOM node
XSequenceCursor result2 = pathExpr.execute(new DOMSource(node));
Resolución de referencias URI
Si ha utilizado instancias de la interfaz URIResolver de JAXP para resolver referencias a la función document() de XSLT, ahora podrá utilizar la interfaz XSourceResolver para llevar a cabo la misma acción. Para resolver referencias en la función document() o en la función fn:doc(), puede establecer una instancia de la interfaz XSourceResolver en una instancia de la interfaz XDynamicContext; para resolver referencias en hojas de estilo importadas a través de declaraciones xsl:import y xsl:include, puede establecer una instancia de la interfaz XSourceResolver en una instancia de la interfaz XStaticContext.
final XFactory factory = XFactory.newInstance();
XSLTExecutable style = factory.prepareXSLT(new StreamSource("style.xsl"));
XDynamicContext dContext = factory.newDynamicContext();
// Create and set an instance of an anonymous inner class as the
// XSourceResolver
dContext.setSourceResolver(new XSourceResolver() {
// Create an item to use as the initial context node for
// transformations in the getSource method
private XItemView fDummyNode =
factory.getItemFactory()
.item(new StreamSource(
new StringReader("<doc/>")));
// Resolve URIs by loading the resource as an XSLT stylesheet
// and evaluating it - return the result as the Source to use
public Source getSource(String href, String base) {
java.net.URI baseURI;
try {
// Get base URI object
baseURI = new java.net.URI(base);
} catch (java.net.URISyntaxException use) {
throw new RuntimeException(use);
}
// Resolved relative reference against base URI
String resolvedURI = baseURI.resolve(href).toString();
// Prepare and execute the stylesheet
XItemView transformResult =
factory.prepareXSLT(new StreamSource(resolvedURI))
.execute(fDummyNode);
return new XItemSource(transformResult);
}
});
XSequenceCursor result = style.execute(new StreamSource("input.xml"), dContext);
Definición de funciones de extensión y funciones externas
Mediante la utilización de JAXP para la evaluación de expresiones XPath, podría registrar una instancia de la interfaz XPathFunctionResolver para proporcionar las implementaciones de funciones de extensión a las que las expresiones XPath podrían invocar. La parte XSLT de JAXP no tiene ningún mecanismo equivalente.
Con la API actual, puede declarar funciones de extensión en una instancia de la interfaz XStaticContext, especificando los tipos previstos de argumentos y el tipo previsto de resultado de la función de llamada, y puede registrar las implementaciones de funciones de extensión en una instancia de la interfaz XDynamicContext. La hoja de estilo XSLT y las expresiones XPath y XQuery pueden invocar a funciones de extensión que registre.
Establecimiento de los valores de parámetros de hojas de estilo y variables externas
Utilizando JAXP, podría proporcionar los valores iniciales de parámetros de hojas de estilo invocando al método Transformer.setParameter y podría suministrar los valores de las variables para expresiones XPath suministrando una instancia de la interfaz XPathVariableResolver. Mediante la API, puede declarar variables utilizando los métodos declareVariable() de la interfaz XStaticContext, especificando un nombre de variable y el tipo previsto de variable. Puede suministrar los valores de parámetros de hojas de estilo, variables XPath y variables externas XQuery a través de uno de los métodos bind() de la interfaz XDynamicContext.
XFactory factory = XFactory.newInstance();
XStaticContext sContext = factory.newStaticContext();
// Declare the XPath variable "query-id" in the static context
QName queryIdVar = new QName("query-id");
sContext.declareVariable(queryIdVar, XTypeConstants.STRING_QNAME);
// Prepare the XPath expression
XItemFactory itemFactory = factory.getItemFactory();
XPathExecutable expr =
factory.prepareXPath("/catalog/product[id eq $query-id]", sContext);
XItemView catalog = itemFactory.item(new StreamSource("catalog.xml"));
XDynamicContext dContext = factory.newDynamicContext();
// Set the value of the "query-id" variable, and evaluate the
// expression with that variable value
dContext.bind(queryIdVar, "ID43785");
XSequenceCursor product1 = expr.execute(catalog, dContext);
// Set the value of the "query-id" variable, and evaluate the
// expression with the new variable value
dContext.bind(queryIdVar, "ID18574");
XSequenceCursor product2 = expr.execute(catalog, dContext);
Transformación de identidad
Otra operación que se utiliza con frecuencia en JAXP es la transformación de identidad. Se trata de una forma muy útil de transformar datos de un formato a otro, por ejemplo, serialización de un árbol DOM o generación de un árbol DOM a partir de sucesos SAX. Es posible llevar a cabo transformaciones utilizando la API. Consulte Cómo llevar a cabo operaciones básicas de XSLT para obtener un ejemplo.
Configuración de tiempo de preparación y de tiempo de ejecución
En JAXP el usuario suministra la mayor parte de la información de configuración del tiempo de ejecución para hojas de estilo XSLT - los valores de los parámetros de la hoja de estilo, URIResolvers, etcétera directamente en los objetos que se utilizan para realizar transformaciones - instancias de la interfaz Transformer y de la interfaz TransformerHandler. De igual modo, puede suministrar la información de configuración para la preparación de hojas de estilo y expresiones XPath directamente en instancias de las clases TransformerFactory y XPathFactory en JAXP.
Con la API, puede suministrar información de configuración que es necesaria en el momento en que se prepara una hoja de estilo o una expresión (enlaces de espacio de nombre, tipos de funciones externas o variables, etcétera) utilizando una instancia de la interfaz XStaticContext. De igual modo, puede proporcionar información de configuración necesaria para evaluar una hoja de estilo o expresión (los valores de las variables, los valores de los parámetros de salida, etc.) de una instancia de la interfaz XDynamicContext, que podrá pasar como argumento a los métodos de ejecución de la interfaz XExecutable y sus subinterfaces.
Esta separación de la información de configuración en un objeto independiente hace que la API sea más segura por lo que respecta a las hebras. La aplicación puede utilizar la misma instancia de la interfaz XExecutable en diferentes hebras sin sincronización. Esto contrasta con JAXP, en que las instancias de las interfaces Transformer, TransformerHandler y XPathExpression no son seguras en cuanto a las hebras; cada hebra que las utiliza tiene que sincronizar el acceso a las instancias compartidas de esos objetos o crear distintas copias específicas para cada hebra.
Manejo de errores
En JAXP, podría suministrar una instancia de la interfaz ErrorHandler para controlar cómo debería responder el procesador ante los errores. En la API, puede conseguirlo suministrando una instancia de la interfaz XMessageHandler en una instancia de la interfaz XStaticContext para los errores del tiempo de preparación o la interfaz XDynamicContext para los errores del tiempo de ejecución.