1

I use fop 2.1 and I need to load an external graphic with an absolute path. I tried this:

    <fo:root xsl:use-attribute-sets="text-attributes">
        <fo:layout-master-set>
         ...

        <fo:page-sequence master-reference="master">
            <xsl:call-template name="pageHeader"/>
            <xsl:call-template name="pageFooter"/>

            <fo:flow flow-name="xsl-region-body">
                ...
            </fo:flow>
        </fo:page-sequence>

   ...

<xsl:template name="pageHeader">
    <fo:static-content flow-name="region-before-first">
        <fo:block>
           <fo:external-graphic src="url({concat('file:/',$logo-image)})" height="15mm" content-height="15mm"/>  
        </fo:block>
    </fo:static-content>
</xsl:template>

$logo-image contains the absolute path like C:/users/.../application/logo.gif

I get the following error:

PM org.apache.fop.events.LoggingEventListener processEvent
SEVERE: Invalid property value encountered in src="url(file:/C:/users/.../application/logo.gif)"  .... Invalid URI specified

Any idea?

I tried also to put ' around like "url('file:/C:/users/.../application/logo.gif')" and else at divers place. No success... :-(


As in some other stylesheets I do have external graphic that functions I tried also take the header into the normal flow ( => not static ). Not really the way to do for a header, but a try... :

    <fo:root xsl:use-attribute-sets="text-attributes">
        <fo:layout-master-set>
         ...

        <fo:page-sequence master-reference="master">
            <!--<xsl:call-template name="pageHeader"/>-->
            <xsl:call-template name="pageFooter"/>

            <fo:flow flow-name="xsl-region-body">
                <xsl:call-template name="pageHeader"/>
                ...
            </fo:flow>
        </fo:page-sequence>

   ...

<xsl:template name="pageHeader">
    <fo:block-container position="absolute" top="10mm" left="10mm">
        <fo:block>
           <fo:external-graphic src="url({concat('file:/',$logo-image)})" height="15mm" content-height="15mm"/>  
        </fo:block>
    </fo:block-container>
</xsl:template>

But: Independantly if I put

<fo:external-graphic src="url({concat('file:/',$logo-image)})" height="15mm" content-height="15mm"/> 

or

<fo:external-graphic src="url({concat('file:///',$logo-image)})" height="15mm" content-height="15mm"/> 

I get same stupid error:

.... Invalid URI specified
jahuer1
  • 377
  • 4
  • 15
  • 1
    if anything the file protocol is `file://` . In your example at least two `//` are missing, see also: https://en.wikipedia.org/wiki/File_URI_scheme. Did you verify your fop processor implementation does support the file protocol? – rene Jul 07 '17 at 14:05

2 Answers2

1

First, simplify matters by getting it to work as a static FO file, independent of XSLT. You can double-back to the XSLT once you have a static target FO file working.

Realize that as @rene commented, you have to use full URI syntax, which may actually require yet another / for local access. (Think protocol://host/path where protocol is 'file' and host is empty here, yielding three slashes in a row):

file:///c:/users

If you still have trouble with this, do a browser walk up the directory tree to make sure that the files and its ancestor directories all exist.

Finally, note that ... isn't valid, in case that's a typo for .. and not a meta-notation about elided path components.

kjhughes
  • 106,133
  • 27
  • 181
  • 240
  • The "..." was only to shorten the path in this post ;-) . It is a real path to my local directory and the file exists. I had already tried the "file:///c:/users" version - but no success. Always getting the same error :-( – jahuer1 Jul 10 '17 at 06:08
  • Yet your self-answer indicates that what I suggested is what in fact worked. Hmm........... – kjhughes Jul 12 '17 at 14:45
0

Oups, I got!

It's a silly Windows slash / backslash thing...!

When getting the image path, I just had to convert the slashes:

string logoImg = BackslashToSlash(Path.GetFullPath(imageFile));
xsltArgumentList.Add("logo-image", logoImg);
...

    public static String BackslashToSlash(String inStr)
    {
        try
        {
            return inStr.Replace("\\", "/");
        }
        catch (Exception)
        {
            return "";
        }
    }

In the stylesheet (xsl) you can even the one-slash version after "file:" (!):

<fo:external-graphic src="url({concat('file:/',$logo-image)})" />

Nevertheless I think it actually should be three-slash one:

<fo:external-graphic src="url({concat('file:///',$logo-image)})"
jahuer1
  • 377
  • 4
  • 15
  • So when you told us that ***logo-image contains the absolute path like C:/users/.../application/logo.gif***, that was not actually true? – kjhughes Jul 10 '17 at 11:09
  • It does contain the absolute path! It's like "C:\Users\username\AppData\Local\applicationName\temp\logo.gif". One of the sucking things is that there was a mix of "\" and "/". :-( – jahuer1 Jul 12 '17 at 12:06
  • **But your question already specifically says that you used forward slash (`/`)**, so saying that the answer to your question is to convert backslash to forward slash is incongruent. – kjhughes Jul 12 '17 at 13:42
  • Might look so - but when you don't know that *this* is the problem, you sometimes don't pay attention first. – jahuer1 Jul 12 '17 at 13:47
  • 2
    You have asked 16 questions and [***accepted***](http://meta.stackoverflow.com/q/5234/234215) 0 to date. That coupled with your posting of a self-answer that's incongruent with the facts of your question indicate that you really should read [ask] and many other of the [help] sections to make better and proper use of this site. Thank you. – kjhughes Jul 12 '17 at 14:26