Search code examples
xmlxsltxsl-foapache-fop

XSL-FO image path problems - changing backslashes to forward


I have the following abc.xml snippet.

<abc>Images\Image.JPG</abc>

and I want to display this image on a PDF. I am using Apache FOP to translate my XML to PDF using XSL-FO. Unfortunately, I cannot figure out a clever way to replace the backslashes as forward slashes. Here is some xsl code I'm playing with:

<fo:external-graphic> <xsl:variable name="fixTest">file:///<xsl:value-of select="abc"/> <xsl:attribute name="src" select="'{translate(@fixTest, '\','/')}'"/> </fo:external-graphic>

I also have some code that I've been trying to be to no avail. Now I know once I figure out how to replace '\' with '/' with the XSL-FO file, I will be able to display my image. However right now I cannot figure out how to do that.

<xsl:attribute name="src"><xsl:value-of select="concat('file:///',translate(@abc, '\', '/'))"/></xsl:attribute>

Does anyone have any idea how I can translate '\' into '/' in my text value of element abc so I can also concatenate file:/// onto that value and set it as my src attribute for fo:external-graphic?


Solution

  • This was a bit too long to write in comments, but in your question you show you are doing this...

    <xsl:attribute name="src" select="'{translate(@fixTest, '\','/')}'"/>
    

    (Although, as you went on to show, it should really be . here, not @fixTest)

    But, this means you have apostrophes nested in a string delimited by apostrophes, which is a syntax error. So, you should have written this to make it syntactically correctly.

    <xsl:attribute name="src" select="'{translate(@fixTest, &quot;\&quot;,&quot;/&quot;)}'"/> 
    

    But this would have shown you what the problem was. select expects an expression. By using delimiting the expression with apostrophes, you have turned it into a string literal, so the expression does not get evaluated. But you didn't need to use apostrophes or curly braces here. You should have written this....

    <xsl:attribute name="src" select="translate(., '\', '\')"/>
    

    Or, to add the "file:///" prefix....

    <xsl:attribute name="src" select="concat('file:///',translate(., '\', '/'))"/>
    

    But there is an even easy way, one where the curly braces (also known as Attribute Value Templates) do apply, and that is to write this...

    <fo:external-graphic src="file:///{translate(., '\', '/')}">
    

    Here, the src attribute does expect a string, and the curly braces are then used to evaluate an expression instead.