Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Pass document as parameter to XSL Translation in Java

Tags:

java

xslt

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&#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>

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?

like image 485
Danny Cohn Avatar asked Jan 16 '12 23:01

Danny Cohn


2 Answers

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.

like image 168
Wayne Avatar answered Sep 22 '22 06:09

Wayne


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.

like image 39
user467257 Avatar answered Sep 25 '22 06:09

user467257