I'm working on addition internationalization to my XSL. I've seen plenty of examples of creating a dictionary.xml file and loading it into my XSL via document('dictionary.xml'). I want to do something similar, but I don't want to create and store the dictionary.xml file on disk, I'd rather build it from SQL at server startup and keep the Document object in memory in Java. I'd like to then pass the dictionary document as a parameter to the transformer so that my XSL translation function can use it. However, it doesn't seem to be working.
Relevant Java code:
Document dictionary = TranslationDictionary.getDictionaryDocument();
transformer.setParameter("dictionary", dictionary);
The dictionary document content:
<dictionary xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<translatedString dictionaryId="BASIC_DETAILS">
<language id="es" value="Detalles Básicos"/>
</translatedString >
<translatedString dictionaryId="VEHICLE_INFORMATION">
<language id="es" value="Información del Vehículo"/>
</translatedString >
<translatedString dictionaryId="STRUCTURE">
<language id="es" value="Estructura"/>
</translatedString >
<translatedString dictionaryId="DRIVER_INFORMATION">
<language id="es" value="Información del Conductor"/>
</translatedString >
<translatedString dictionaryId="MAINTENANCE_AND_FEUL">
<language id="es" value="Mantenimiento & Combustible"/>
</translatedString >
<translatedString dictionaryId="PURCHASING">
<language id="es" value="Compra"/>
</translatedString >
</dictionary>
The XSL file:
<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>
But I get nothing. I've tried just doing a copy of $document/document to confirm that I'm not having an xpath issue, and its not that, because that gives me a copy of the full document. It's as if the XSL is seeing $dictionary as a string instead of a node. Any clues?
Use a URIResolver
instead of a parameter. First, create the resolver like this:
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;
}
}
Use it like this:
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));
And reference it in your stylesheet by name:
<xsl:variable name="dict" select="document('dictionary')"/>
This is just a toy example, of course. You can make your URIResolver
as full-featured as necessary.
Ok, I made a skeleton copy of your code. This is going to sound bizarre, but after you create your dictionary document in the java code, and before you set it as a parameter for the transformer, just invoke the method:
dictionary.getDocumentElement();
then it works! Looks like a bug in the way saxon is handling a parameter thats a document, where it requires some kind of initialisation which hasnt been done ? I'm not digging into the debugger.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With