Search code examples
xsltpdf-generationxsl-foapache-fop

XSL FO Pass dynamic value from the HTML to XSLT variable


I have trying to create pdf from html file using FOP. My requirement is, I want to pass variable value at run time. How can I pass variable value at run time?


Solution

  • It is not clear at what point you can inject "variables" nor how you expect to do them. Here's a sample that may provide some inspiration. It only uses a simple identity-translate and omits all the FO stuff for brevuty.

    General principle -- put in a hidden div with some codes that are variables. For instance and simplicity, your input HTML now has this:

    <html>
        <div class="variables" style="display:none">
            <div class="var_1" data-value="variable 1 value"/>
            <div class="var_2" data-value="variable 2 value"/>
            <div class="var_3" data-value="variable 3 value"/>
        </div>
        <div>
            <div>Var 1 Value: <span class="variable" data-ref="var_1"/></div>
            <div>Var 2 Value: <span class="variable" data-ref="var_2"/></div>
            <div>Var 3 Value: <span class="variable" data-ref="var_3"/></div>
        </div>
    </html>
    

    And you modify your XSL for a template that matches on a span where you want to insert the variable:

    <xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
        <xsl:template match="span[@class='variable']">
            <xsl:variable name="lookup">
                <xsl:value-of select="@data-ref"/>
            </xsl:variable>
            <span>
                <xsl:value-of select="//div[@class=$lookup]/@data-value"/>
            </span>
        </xsl:template>
        <xsl:template match="node()">
            <xsl:copy>
                <xsl:copy-of select="@*"/>
                <xsl:apply-templates/>
            </xsl:copy>
        </xsl:template>
    </xsl:stylesheet>
    

    The output of this would be:

    <html>
    <div class="variables" style="display:none">
      <div class="var_1" data-value="variable 1 value"></div>
      <div class="var_2" data-value="variable 2 value"></div>
      <div class="var_3" data-value="variable 3 value"></div>
    </div>
    <div>
      <div>Var 1 Value: <span>variable 1 value</span></div>
      <div>Var 2 Value: <span>variable 2 value</span></div>
      <div>Var 3 Value: <span>variable 3 value</span></div>
    </div>
    </html
    

    Of course, you could expand that to include a template to strip the div whose class is variables for instance to not have it in the output or processed by your templates.