0

I need to grab a couple of images and put them into pdf generated via Apache FOP. Outside of eXist, I have no problems. With eXist, the template does not work properly, there is no image in the output—maybe there is a problem with paths.

The structure of “files” is:

project/data/file.xml
project/data/img/*pictures.jpg

Testing sources:

<figure>
    <graphic url="img/tealover.jpg"/>
</figure>

<figure>
    <graphic url="./img/tealover.jpg"/>
</figure>

<figure>
    <graphic url="/db/apps/karolinum-apps/data/img/tealover.jpg"/>
</figure>

Template:

<xsl:template match="tei:figure/tei:graphic">
    <fo:block>
        <fo:external-graphic src="{@url}" xsl:use-attribute-sets="images"/>
    </fo:block>
    <xsl:apply-templates/>
</xsl:template>

Where could be the problem? Am I missing some setting of eXist? When collecting images during ePub production, there is no problem with this.

UPDATE

XSL-FO output:

<fo:block>
    <fo:external-graphic width="50%" content-height="100%" content-width="scale-to-fit" scaling="uniform" src="img/tealover.jpg"/>
</fo:block>
<fo:block>
    <fo:external-graphic width="50%" content-height="100%" content-width="scale-to-fit" scaling="uniform" src="./img/tealover.jpg"/>
</fo:block>
<fo:block>
    <fo:external-graphic width="50%" content-height="100%" content-width="scale-to-fit" scaling="uniform" src="/db/apps/karolinum-apps/data/img/tealover.jpg"/>
</fo:block>
Honza Hejzl
  • 874
  • 8
  • 23
  • Do you have some way to check the created FO? Is the `src` attribute empty? – Martin Honnen Jan 22 '16 at 17:49
  • Of cource, I checked that whilst trying to figure out what is going about, it is identical as the one in the source. I will ensure once more. But I guess the problem may be somewhere else. – Honza Hejzl Jan 22 '16 at 21:17

2 Answers2

1

The XSL-FO processor has no idea how to retrieve the images from those URL's as it has no knowledge where to resolve those paths against.

You should instead use absolute URLs that the XSL-FO processor can dereference, so for example if your image is stored in eXist at this path:

/db/apps/karolinum-apps/data/img/tealover.jpg

You should instead use the URL:

http://localhost:8080/exist/rest/db/apps/karolinum-apps/data/img/tealover.jpg.

I am assuming that eXist is running on localhost port 8080, if not then just adjust the URL above to reflect your setup.

adamretter
  • 3,885
  • 2
  • 23
  • 43
  • Thanks! It works and it is very reasonable! However, before I will mark the question as answered, what if I disabled the REST functionality of eXist at all (it is recommended in the new book from O’Reilly)? Is there any solution? – Honza Hejzl Jan 25 '16 at 08:04
  • Basically your XSL-FO processor knows how to access absolute URI's. If you wanted to disable the REST API, you could consider using URI's that point into the WebDAV or RESTXQ API's. If you wanted to also disable those, you could resolve your binary files paths against `$EXIST_HOME/webapp/WEB-INF/data/fs` which is where eXist actually puts your binary files. So, if your $EXIST_HOME was `/usr/local/eXist` you would pass something like the following URL: `files:///usr/local/eXist/webapp/WEB-INF/data/fs/db/apps/karolinum-apps/data/img/tealover.jpg`. However this approach is undocumented/fragile. – adamretter Jan 25 '16 at 11:15
  • Also the eXist O'Reilly book only recommends disabling what you don't need. You can still use the REST API but not make it accessible to anyone else if you want. – adamretter Jan 25 '16 at 11:16
  • Thanks! My head is a bit spinning! – Honza Hejzl Jan 25 '16 at 13:23
  • Sorry that URL should start `file:///` not `files:///`. – adamretter Jan 25 '16 at 14:21
  • 2
    You should find that FOP supports `xml:base`, since the Apache JIRA issue about it is closed (https://issues.apache.org/jira/browse/FOP-1744), so you should be able to set `xml:base` on the `fo:root` and use relative URLs elsewhere. – Tony Graham Jan 25 '16 at 14:44
  • The problem is I need to slightly change the tail of the path (every book resides in its own place. At the moment, I am not able to concatenate properly in the stylesheet. – Honza Hejzl Jan 27 '16 at 08:18
0

It seems this does the trick:

<xsl:template match="tei:figure/tei:graphic">
    <fo:block>
        <fo:external-graphic src="url('{resolve-uri(@url, base-uri(.))}')" xsl:use-attribute-sets="images"/>
    </fo:block>
    <xsl:apply-templates/>
</xsl:template>

UPDATE

Interesting! At first it worked like a charm. Later, I slightly rearranged the project’s structure (but the environment near the document is practically the same) and now it does not work. It logs:

exerr:ERROR Exception while transforming node: Base URI {} is not an absolute URI [at line 11, column 19] In function:
fop:render-pdf(node()*) [12:5:/db/apps/karolinum-apps/modules/create-pdf.xqm]

but the problem, apparently, is in this line of code.

Even if I try <xsl:value-of select="resolve-uri(@url, base-uri(.))"/>, it complains

exerr:ERROR Exception while transforming node: Base URI {} is not an absolute URI [at line 16, column 9]

Can’t understand such tiny details at the moment.

Honza Hejzl
  • 874
  • 8
  • 23
  • What happens if you do `base-uri(root(.))`? – adamretter Jan 28 '16 at 12:19
  • The same error. I am testing intensively and it seems the way is to leave the XSLT method and focus on tuning the FO processor. At the moment, it works to supply the `` in `fop.conf` served dynamically to the `render-fop()` function with the absolute path to images via `rest`. However, the same with fonts and `` does not work, even if they are really reachable through the `rest`. Really unhappy with this stuff. – Honza Hejzl Jan 28 '16 at 13:02
  • Answered here: http://stackoverflow.com/questions/35038690/images-in-xsl-fo-in-exist-db/35083165#35083165 – Honza Hejzl Jan 29 '16 at 11:17