fo:external-graphic with parameter in template file

Viewed 948

I'm trying something straight-forward and I would say not too complex. But I cannot figure out how to do it: I want to have images in an XSL-FO document.

In detail:

I have two files, one contains the logical contents of my text, the other logically the formatting instructions. I'm using the Apache application fop to compile this into a PDF:

fop -q -xml contents.xml -xsl formatting.xsl -pdf output.pdf

This works fine for pure text. The file contents.xml contains things like this:

<part>
  Lorem ipsum bla
</part>

And the file formatting.xsl contains things like this:

<xsl:stylesheet ...>
  <xsl:template match="part">
    <fo:block ...>
      <xsl:apply-templates/>
    </fo:block>
  </xsl:template>
</xsl:stylesheet>

Now I want to add some images. Because it will be many images which are all to be similarly formatted, I would like to have a simple abstract thing for each image in the contents.xml passing a parameter to a template. E.g. <img path="path/to/my/image.png"/> would be fine, but also something like <img>path/to/my/image.png</img> or even <img><path value="path/to/my/image.png"/></img> would be okay.

The template in formatting.xsl shall understand and use the passed parameter and put it in a <fo:external-graphic src="[parameter-value]"\>.

Also, I need to be able to provide one of several formatting files to achieve different PDFs for the same contents but with different formatting (e.g. a paperback version, a hardcover version, and a manuscript version of the same contents).

But all my trials up to now have failed. The only thing I managed was to have a solution without a passed parameter, so the path to the image then was hardcoded in the formatting file.

I tried a lot of variants with <xsl:call-template>, <xsl:with-param>, and also with <xsl:attribute name="src">, etc., but up to now nothing worked. Either the fop complained about a wrong usage or the result didn't show an image in the PDF.

I have the feeling this must be something very simple and typical which many people want to do, but still I didn't find any example implementing something like my case.

Can anybody give me an example on how to do this?

EDIT:

My favorite usage in the contents.xml would be <img path="img/001_title.png"/> but in the formatting.xsl I have no clue how to formulate my template to make this work. Without the parameter path I can use this:

<xsl:template match="img">
  <fo:block>
    <fo:external-graphic src="img/001_title.png"/>
  </fo:block>
</xsl:template>

But as I already wrote, this then hardcodes the path and cannot be reused to insert another picture with another path.

I also tried e.g. this in formatting.xsl:

<xsl:template match="img">
  <xsl:param name="path"/>
  <fo:block>
    <fo:external-graphic src="$path"/>
  </fo:block>
</xsl:template>

But then in contents.xml to pass the parameter value I was supposed to use sth like

<xsl:call-template name="img">
  <xsl:with-param name="path" select="img/001_title.png"/>
</xsl:call-template>

which earned me an error from fop, stating that the xsl stuff was illegal at the place in contents.xml where I used it.

Also, the use of the parameter in the template as stated above probably isn't as it's supposed to be because I think this would need something like using <xsl:value-of select="$path"/> or similar but I don't know how to do that if the value is supposed to be used within the double quotes of an attribute.

For this, it seems the syntax

<fo:external-graphic>
  <xsl:attribute name="src">
    <xsl:value-of select="$path"/>
  </xsl:attribute>
</fo:external-graphic>

is supposed to be used. But I also couldn't use this because, again, it is unclear to me how to use it in the end from the contents.xml file.

1 Answers

Wouldn't it be like your content.xml would contain things like:

<contents>
<part>
  Lorem ipsum bla
</part>
<img path="img/001_title.png"/>
<part>
  Lorem ipsum bla
</part>
<img path="img/002_title.png"/>
</contents>

Then in your XSL you use:

<xsl:template match="img">
<fo:external-graphic>
  <xsl:attribute name="src">
    <xsl:value-of select="@path"/>
  </xsl:attribute>
</fo:external-graphic>
</xsl:template>

Your XML can contain the images with paths and they can point anywhere and the XSL when it encounters one, it outputs it in the XSL FO. That template uses @path attribute directly from img tag in XML.

Then any type of path would work:

<img path="relative/to/something.png"/>
<img path="http://mywebsite.com/logo.png"/>
<img path="http://mywebsite.com/mycode.php?getimage='123242'"/>
Related