2012-01-16 19 views
7

Estoy trabajando en la internacionalización de la adición a mi XSL. He visto muchos ejemplos de cómo crear un archivo dictionary.xml y cargarlo en mi XSL a través de un documento ('dictionary.xml'). Quiero hacer algo similar, pero no quiero crear y almacenar el archivo dictionary.xml en el disco, prefiero construirlo desde SQL al inicio del servidor y mantener el objeto Document en la memoria en Java. Me gustaría pasar el documento del diccionario como un parámetro al transformador para que mi función de traducción XSL pueda usarlo. Sin embargo, no parece estar funcionando.Pase el documento como parámetro a la traducción XSL en Java

Relevante código Java:

Document dictionary = TranslationDictionary.getDictionaryDocument(); 
transformer.setParameter("dictionary", dictionary); 

El contenido diccionario documento:

<dictionary xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"> 
    <translatedString dictionaryId="BASIC_DETAILS"> 
     <language id="es" value="Detalles B&#225;sicos"/> 
    </translatedString > 
    <translatedString dictionaryId="VEHICLE_INFORMATION"> 
     <language id="es" value="Informaci&#243;n del Veh&#237;culo"/> 
    </translatedString > 
    <translatedString dictionaryId="STRUCTURE"> 
     <language id="es" value="Estructura"/> 
    </translatedString > 
    <translatedString dictionaryId="DRIVER_INFORMATION"> 
     <language id="es" value="Informaci&#243;n del Conductor"/> 
    </translatedString > 
    <translatedString dictionaryId="MAINTENANCE_AND_FEUL"> 
     <language id="es" value="Mantenimiento &amp; Combustible"/> 
    </translatedString > 
    <translatedString dictionaryId="PURCHASING"> 
     <language id="es" value="Compra"/> 
    </translatedString > 
</dictionary> 

El archivo XSL:

<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:dc="http://www.test.com"> 
    <xsl:param name="dictionary"/> 
    <xsl:param name="language" select="'es'"/> 


<xsl:template match="/"> 
<xsl:message> 
    <xsl:copy-of select="$dictionary/dictionary/translatedString[@dictionaryId='BASIC_DETAILS']/language[@id='es']/@value"/> 
</xsl:message> 

</xsl:template> 

Pero no consigo nada. Intenté simplemente hacer una copia de $ documento/documento para confirmar que no estoy teniendo un problema xpath, y no es eso, porque eso me da una copia del documento completo. Es como si el XSL estuviera viendo $ dictionary como una cadena en lugar de un nodo. ¿Alguna pista?

+0

Estoy usando Saxon9 como mi XSLT, si eso ayuda –

+0

Eso ayuda y señala el hecho de que esta pregunta es específica del procesador XSLT y, como tal, pertenece a la etiqueta "xsltprocessor". –

Respuesta

4

Ok, hice una copia básica de su código. Esto va a sonar extraño, pero después de crear el diccionario documento en el código de Java, y antes de establecerlo como un parámetro para el transformador, simplemente invocar el método:

dictionary.getDocumentElement(); 

entonces funciona! Parece un error en la forma en que saxon maneja un parámetro que es un documento, donde requiere algún tipo de inicialización que no se ha hecho. No estoy investigando el depurador.

+0

Intenté una manera diferente de crear el documento DOM y luego noté que aunque en el mensaje XSL el elemento raíz era "diccionario", si escribía el documento en el disco era "Diccionario". Una vez que cambié mi xpath, funcionó. ¡Gracias! –

-2

afecta el cambio

select="$dictionary 

a

select="node-set($dictionary) 

ayuda?

+0

No, no ayuda –

+0

¿De qué estás hablando? Si había un error en el analizador sintáctico que causaba que $ $ dictionary por algún motivo se tratara como un valor escalar en lugar de un conjunto de nodos, entonces habría identificado la causa del problema. Como sucedió, su comportamiento fue causado por un error en el analizador saxon (como descubrí y publicado posteriormente), pero no este en particular. – user467257

+0

"identifiqué la causa del problema", y posiblemente también lo solucioné, debería haber agregado, si la llamada del conjunto de nodos forzó la interpretación del tipo en el formato correcto (si la causa fue la interpretación del tipo). – user467257

8

Utilice un URIResolver en lugar de un parámetro. En primer lugar, crear el sistema de resolución de esta manera:

public class DocURIResolver implements URIResolver { 

    final Map<String, Document> documents; 

    public DocURIResolver(final Map<String, Document> documents) { 
     this.documents = documents; 
    } 

    public Source resolve(final String href, final String base) { 
     final Document doc = documents.get(href); 
     return (doc != null) ? new DOMSource(doc) : null; 
    } 
} 

utilizar de esta manera:

Document dictionary = TranslationDictionary.getDictionaryDocument(); 
Map<String, Document> docs = new HashMap<String, Document>(); 
docs.put("dictionary", dictionary); 
// transformer is your javax.xml.transform.Transformer 
transformer.setURIResolver(new DocURIResolver(docs)); 

y referencia en su hoja de estilo por su nombre:

<xsl:variable name="dict" select="document('dictionary')"/> 

Esto es sólo un ejemplo de juguete, por supuesto. Puede hacer que su URIResolver tenga todas las características necesarias.

+0

Prefiero no usar un URIResolver personalizado. ¿Algún otro pensamiento? –

+0

@DannyCohn - ¿Alguna razón en particular? –

+0

Parece una capa adicional de complejidad que no debería ser necesaria. Si tengo que hacerlo lo haré, pero no creo que lo que estoy haciendo sea lo suficientemente complejo como para requerir un URIResolver, así que me gustaría probar algo menos hack-ish primero –

3

Pasar un nodo de documento DOM como parámetro para una transformación de Saxon debería funcionar (DOM no es la representación de árbol más eficiente, por un largo camino, pero debería funcionar). Entonces debería pasar DOMSource que envuelve el documento DOM. Normalmente empiezo haciendo xsl: copy-of select = "$ doc", y parece que lo has hecho y confirmado que el valor se está pasando correctamente. Si no obtiene nada en respuesta a las selecciones de XPath dentro del documento, esto generalmente significa que las expresiones XPath son incorrectas. Las razones más comunes son olvidarse del nodo raíz (documento) y olvidarse de los espacios de nombres. Pero me temo que no hay evidencia de tales errores en el código que nos ha mostrado, suponiendo que el DOM refleje el XML que ha mostrado en su publicación.

Su publicación sugiere que ha compilado el documento DOM mediante programación. Es posible que haya creado un DOM que Saxon no puede procesar por alguna razón: las interfaces DOM no son muy robustas y a veces hay dificultades cuando las personas usan una implementación DOM que no ha sido probada con Saxon.

También puede probar su hoja de estilo ejecutándola desde la línea de comandos: puede proporcionar el valor del parámetro $ dictionary utilizando + dictionary = dict.xml (el '+' inicial hace que se reconozca como el nombre de un archivo que se debe analizar).

+0

Voy a intentar esto cuando entre a la oficina. También voy a tratar de construir el documento DOM de una manera diferente para confirmar que está bien construido. Usted dice que DOM no es la representación de árbol más eficiente. ¿Puedes recomendar algo más? Estoy ciertamente dispuesto a cambiar eso. –

Cuestiones relacionadas