I'm using XSLT Dita OT to generat PDF files.
For the publicationproces its possible to generate a translation files in EN, FR, DE, IT. Now i used the code as below to manage my output.
I this case the language is a metadata and thats why i use the "# attribute"
But after publishing my code it isn't working. can someone help me with this.
<xsl:choose>
<xsl:when test="#xml:lang = 'EN'">
<fo:block-container xsl:use-attribute-sets="languagecontainer" top="25mm">
<fo:block xsl:use-attribute-sets="languageblock">ENGLISH</fo:block>
</fo:block-container>
</xsl:when>
<xsl:when test="#xml:lang = 'FR'">
<fo:block-container xsl:use-attribute-sets="languagecontainer" top="55mm">
<fo:block xsl:use-attribute-sets="languageblock">FRANÇAIS</fo:block>
</fo:block-container>
</xsl:when>
<xsl:when test="#xml:lang = 'DE'">
<fo:block-container xsl:use-attribute-sets="languagecontainer" top="85mm">
<fo:block xsl:use-attribute-sets="languageblock">DEUTSCH</fo:block>
</fo:block-container>
</xsl:when>
<xsl:when test="#xml:lang = 'IT'">
<fo:block-container xsl:use-attribute-sets="languagecontainer" top="115mm">
<fo:block xsl:use-attribute-sets="languageblock">ITALIANO</fo:block>
</fo:block-container>
</xsl:when>
<xsl:when test="#xml:lang = 'ES'">
<fo:block-container xsl:use-attribute-sets="languagecontainer" top="145mm">
<fo:block xsl:use-attribute-sets="languageblock">ESPAÑOL</fo:block>
</fo:block-container>
</xsl:when>
<xsl:otherwise>
<fo:block>
<xsl:text>no result</xsl:text>
</fo:block>
</xsl:otherwise>
It will be useful to insert debug <xsl:message> instruction before the <xsl:choose> to analyze your problem.
<xsl:message select="'context=',."/>
<xsl:message select="'#xml:lang=',#xml:lang"/>
If the context is not a element, referencing #xml:lang is no meaning. Or if #xml:lang is not the expected one ('FR', 'DE' ,'IT' ,'ES'), you should correct your template to match the actual #xml:lang attribute value.
Related
I have a table with 2 columns and multiple rows. I need to have only the outer border of the table and nothing as column separator. I could not find any attributes.
<xsl:attribute-set name="Cell-Default">
<xsl:attribute name="border-color">rgb(175,175,175)</xsl:attribute>
<xsl:attribute name="border-width">thin</xsl:attribute>
<xsl:attribute name="border-bottom-style">solid</xsl:attribute>
<xsl:attribute name="border-right-style">solid</xsl:attribute>
<xsl:attribute name="start-indent">.1cm</xsl:attribute>
<xsl:attribute name="end-indent">.1cm</xsl:attribute>
</xsl:attribute-set>
<fo:table-body>
<fo:table-row height=".9cm" display-align="center" background-color="rgb(235,235,236)">
<fo:table-cell xsl:use-attribute-sets="Cell-Default">
<fo:block>
<fo:inline color="rgb(0, 0, 0)">QUOTE NUMBER: </fo:inline>
<fo:inline><xsl:value-of select="../QuoteNumber"/></fo:inline>
</fo:block>
</fo:table-cell>
</fo:table-row>
</fo:table-body>
I have xslt template that generates pdf using Apache FOP. I have problem that background image cannot be found. I have tried absolute paths, relative paths and many else, but nothing happens. Could any of you help me ?
I have tried following paths, but it did not help.
c:/Projects/demo/src/main/resources/certificate.png is absolute path
background-image="c:/Projects/demo/src/main/resources/certificate.png"
background-image="file:///c:/Projects/demo/src/main/resources/certificate.png"
background-image="certificate.png"
background-image="./certificate.png"
background-image="url(certificate.png)"
background-image="url(./certificate.png)"
background-image="url(c:/Projects/demo/src/main/resources/certificate.png)"
background-image="url(file:///c:/Projects/demo/src/main/resources/certificate.png)"
background-image="url(file:///./certificate.png)"
<fo:block-container position="absolute" height="210mm" width="297mm"
background-image="c:/Projects/demo/src/main/resources/certificate.png"
background-position="right" background-color="transparent">
<!-- Name -->
<fo:block-container absolute-position="fixed"
top="95mm">
<fo:block
letter-spacing="8px"
font-size="22pt"
color="#333333"
font-family="BrandonBlack"
text-align="center">
<xsl:value-of select="data/user"/>
</fo:block>
</fo:block-container>
<!-- Course Name -->
<fo:block-container absolute-position="fixed"
top="135mm">
<fo:block
letter-spacing="5px"
font-size="19pt"
color="#7b5f6f"
font-family="BrandonBlack"
text-align="center">
<xsl:value-of select="data/course"/>
</fo:block>
</fo:block-container>
<!-- Date -->
<fo:block-container absolute-position="fixed"
top="189mm" left="214mm">
<fo:block
letter-spacing="2px"
font-size="12pt"
color="#333333"
font-family="BrandonBlack">
<xsl:value-of select="data/date"/>
</fo:block>
</fo:block-container>
</fo:block-container>
You need to use url() and wrap the URL in single quotes, like so:
<fo:block-container background-image="url('./certificate.png')" />
XML file:
<formattedEgGesamt>270.94</formattedEgGesamt>
<formattedEgGesperrt>50.00</formattedEgGesperrt>
<formattedHgGesamt>78.18</formattedHgGesamt>
<formattedHgGesperrt>4.00</formattedHgGesperrt>
In my XSL file, I declare 4 variables:
<xsl:variable name="HGGesamt">
<xsl:value-of select="format-number(/Basis/PersonenkontoDTO/formattedHgGesamt,'#.00')"/>
</xsl:variable>
<xsl:variable name="HGGesperrt">
<xsl:value-of select="format-number(/Basis/PersonenkontoDTO/formattedHgGesperrt,'#.00')"/>
</xsl:variable>
<xsl:variable name="EGGesamt">
<xsl:value-of select="format-number(/Basis/PersonenkontoDTO/formattedEgGesamt,'#.00')"/>
</xsl:variable>
<xsl:variable name="EGGesperrt">
<xsl:value-of select="format-number(/Basis/PersonenkontoDTO/formattedEgGesperrt,'#.00')"/>
</xsl:variable>
These variables are used to calculate the difference between formattedHgGesamt and formattedHgGesperrt, and formattedEgGesamt and formattedEgGesperrt.
The result should be printed.
Here's the code used to print the 2 results:
<fo:table-cell padding="3pt" display-align="center" border-style="solid" border-width="1pt" border-color="white">
<fo:block font-family="Courier" text-align="right" font-weight="bold">
<xsl:value-of select="format-number(exsl:node-set($HGGesamt)-exsl:node-set($HGGesperrt),'#.00')"/> €
</fo:block>
</fo:table-cell>
<fo:table-cell padding="3pt" display-align="center" border-style="solid" border-width="1pt" border-color="white">
<fo:block font-family="Courier" text-align="right" font-weight="bold">
<xsl:value-of select="format-number(exsl:node-set($EGGesamt)-exsl:node-set($EGGesperrt),'#.00')"/> €
</fo:block>
</fo:table-cell>
The result of the first lines of code, concerning HGGesamt and HGGesperrt are printed and the result is right.
For the EGGesamt-EGGesperrt, it only prints "NaN"
Does anybody have an idea, why?
There seems to be a non-digit character with Unicode 8203 (U+200B, zero width space) in the data of <formattedEgGesamt>270.94</formattedEgGesamt>,. after the decimal point. So that way the number computations result in NaN.
As #martin-honnen said.
There's also easier ways to get the numbers that you want, e.g.
<xsl:variable name="HGGesamt" select="/Basis/PersonenkontoDTO/formattedHgGesamt"/>
<xsl:variable name="HGGesperrt" select="/Basis/PersonenkontoDTO/formattedHgGesperrt"/>
<xsl:variable name="EGGesamt" select="/Basis/PersonenkontoDTO/formattedEgGesamt"/>
<xsl:variable name="EGGesperrt" select="/Basis/PersonenkontoDTO/formattedEgGesperrt"/>
and:
<xsl:value-of select="format-number($HGGesamt - $HGGesperrt,'#.00')"/> €
...
<xsl:value-of select="format-number($EGGesamt - $EGGesperrt,'#.00')"/> €
I want to force a line break after a string length of 14 characters in a PDF generated with AH Formatter. So this is my xsl code without any attempt of line breaking:
<xsl:attribute-set name="big" use-attribute-sets="bold">
<xsl:attribute name="font-size">38pt</xsl:attribute>
<xsl:attribute name="line-height">28.84pt</xsl:attribute>
<xsl:attribute name="text-align">center</xsl:attribute>
<xsl:attribute name="letter-spacing">1mm</xsl:attribute>
</xsl:attribute-set>
<xsl:attribute-set name="small" use-attribute-sets="bold">
<xsl:attribute name="font-size">27pt</xsl:attribute>
<xsl:attribute name="line-height">27pt</xsl:attribute>
<xsl:attribute name="text-align">center</xsl:attribute>
<xsl:attribute name="letter-spacing">1mm</xsl:attribute>
</xsl:attribute-set>
<xsl:choose>
<xsl:when test="string-length($count_cover)>=14">
<fo:block xsl:use-attribute-sets="small">
<xsl:apply-templates/>
</fo:block>
</xsl:when>
<xsl:otherwise>
<fo:block xsl:use-attribute-sets="big">
<xsl:apply-templates/>
</fo:block>
</xsl:otherwise>
</xsl:choose>
Is it possible to force a line break with XSL-FO?
If the title can be converted into string, you can insert <fo:block/> as line break.
<xsl:variable name="cover_title" as="xs:string" select="'Very Long Cover Title! Very Long Cover Title! Very Long Cover Title! '"/>
<xsl:variable name="count_cover" as="xs:integer" select="string-length($cover_title)"/>
<xsl:variable name="lf_position" as="xs:integer" select="14"/>
<xsl:template match="/">
<xsl:choose>
<xsl:when test="$count_cover gt $lf_position">
<fo:block xsl:use-attribute-sets="small">
<xsl:analyze-string select="$cover_title" regex=".{{1}}">
<xsl:matching-substring>
<xsl:value-of select="."/>
<xsl:if test="position() eq $lf_position">
<fo:block/>
</xsl:if>
</xsl:matching-substring>
<xsl:non-matching-substring/>
</xsl:analyze-string>
</fo:block>
</xsl:when>
<xsl:otherwise>
<fo:block xsl:use-attribute-sets="big">
<xsl:value-of select="$cover_title"/>
</fo:block>
</xsl:otherwise>
</xsl:choose>
</xsl:template>
The result:
<fo:block font-weight="bold" font-size="27pt" line-height="27pt" text-align="center" letter-spacing="1mm">Very Long Cove<fo:block/>r Title! Very Long Cover Title! Very Long Cover Title! </fo:block>
However this method ignores word boundaries and hyphenation control. If you are intending to make book cover title, it will better to introduce AH Formatter extensions by using fo:block-container.
Use fo:block-container for your title in fixed position and size in the cover page.
Set property #overflow="condense" with #axf:overflow-condense=”font-size".
https://www.antennahouse.com/product/ahf60/docs/ahf-ext.html#axf.overflow-condense
Inside the fo:block-container, place fo:block that stores title contents.
You can get desired result because AH Formatter automatically adjust the font-size according to the content volume.
[Example]
<fo:block-container position="absolute" top="..." left="..." width="..." height="..." overflow="condense" axf:overflow-condense="font-size" font-size="27pt" text-align="center">
<fo:block>
<fo:inline>Very Long Cover Title! Very Long Cover Title! Very Long Cover Title!</fo:inline>
</fo:block>
</fo:block-container>
If you're trying to break words (rather than, e.g., part numbers), then enabling hyphenation may give you a better result than breaking after a fixed number of characters.
You can use linefeed-treatment="preserve" and insert
instead of fo:block, as this answer to Inserting a line break in a PDF generated from XSL FO using <xsl:value-of> notes. Which you can do with <xsl:value-of select="replace(., '(.{14})', '$1
')" />
You can instead insert a zero-width space, , after every 14th character and let AH Formatter break on the zero-width space:
<xsl:template match="text()">
<xsl:value-of
select="replace(replace(., '(\P{Zs}{14})', '$1'),
'(\p{Zs})',
'$1')" />
</xsl:template>`
The inner replace() inserts the character after every 14 non-space characters, and the outer replace() fixes it if the 15th character was a space character.
If you're using a proportional-width font, some sequences of 14 characters (excluding, e.g., 14 constant-width lining numbers) will take more or less width than others, so you might want to insert between more characters so that AH Formatter can do its best to fill the line before breaking.
You can use axf:word-break="break-all" to enable line breaking even inside a word. See https://www.antennahouse.com/product/ahf63/ahf-ext.html#axf.word-break
You can't force a line break in FO, but you can split up the string into separate FO blocks.
<xsl:choose>
<xsl:when test="string-length($count_cover) >= 14">
<fo:block><xsl:value-of select="substring($count_cover, 1, 13)"/></fo:block>
<fo:block><xsl:value-of select="substring($count_cover, 14)"/></fo:block>
</when>
<xsl:otherwise>
<fo:block>
<xsl:value-of select="$count_cover"/>
</fo:block>
</xsl:otherwise>
</xsl:choose>
I am using below line to achive dynamic row height i.e the height should match with the left column .
But I also need to split the row into different cells ? When I am using simple fo:block-cell attrbutes ,I am not getting dynamic row hight . How can achive both dynamic row hieght and cells ??
<fo:table-row display-align="center">
<xsl:for-each select="xalan:distinct(Number)">
<fo:table-cell block-progression-dimension="auto" >
<fo:block-container height="10mm">
<fo:block font-size="9pt" border-right-width="0.1mm" border-right-style="solid" border-right-color="red" >
<xsl:value-of select="">
<xsl:variable name="">
<xsl:value-of select="">
</xsl:variable>
<xsl:if test="">
<xsl:value-of select=""/>
</xsl:if>
</fo:block>
</fo:block-container>
</fo:table-cell>
snapshot
Update -
I think one way that it could be done is to insert a vertical line after every cell value .Tried this , but somehow vertical line is not printing .
<fo:table-cell number-columns-spanned="2" xsl:use-attribute-sets="myBorder" display-align="center">
<fo:block font-size="10pt" text-align="center">
<fo:table>
<fo:table-body>
<fo:table-row>
<xsl:for-each select="../../../rateDetails[toGeography/sequence = $currentSequence]">
<fo:table-cell><!-- block-progression-dimension="auto" border-right-width="0.1mm" border-right-style="solid" border-right-color="black" text-align="center"> -->
<fo:block-container>
<fo:block font-size="9pt"><!-- border-right-width="0.1mm" border-right-style="solid" border-right-color="black" text-align="center"> -->
<xsl:call-template name="currencySymbol">
<xsl:with-param name="currencyCode" select="$currencyCode" />
</xsl:call-template>
<xsl:value-of select="util:formatCurrency(rate,$language,$countryCode)" />
</fo:block>
</fo:block-container>
<fo:block-container reference-orientation="90">
<fo:block>
<fo:leader leader-pattern="rule" leader-length="100%" rule-style="solid" rule-thickness="0.1mm" color="black"/>
</fo:block>
</fo:block-container>
</fo:table-cell>
</xsl:for-each>
Is there anything that I am missing for vertical line insertion .
snapshot2
If you move the border and padding properties to the fo:table-cell, the border will be the full height of the cell:
<fo:table-cell border-right="0.1mm solid red">
By setting fo:block-container/#height, you're probably finding that the text in a cell can overflow the 10mm but only the 10mm is being used to determine the row height. If you remove the fo:block-container, you should get a variable-height table row.
The new code sample makes things a bit clearer: you're using 2 nested tables.
That's another complication you don't need.
Just use 1 table.
In the first column, place all the geography codes into the first cell. It does not matter how many there are: if you have 1 geography code, the cell will be one line high. If you have 16 geography codes in this cell, the cell will automatically resize to be 3 lines high.
The rest of the row contains cells with the price information. On these cells, define the right border to generate the red vertical line.
<fo:table>
<fo:table-column column-width="..mm" column-number="1"/>
<fo:table-column column-width="..mm" column-number="2"/>
...you'll have to add some code here to add the correct number of columns to your table...
<fo:table-body>
<fo:table-row>
<fo:table-cell>
...place the code to insert the country codes here....
</fo:table-cell>
<xsl:for-each select="../../../rateDetails[toGeography/sequence = $currentSequence]">
<fo:table-cell block-progression-dimension="auto" border-right-width="0.1mm" border-right-style="solid" border-right-color="black" text-align="center">
<fo:block-container>
<fo:block font-size="9pt">
<xsl:call-template name="currencySymbol">
<xsl:with-param name="currencyCode" select="$currencyCode" />
</xsl:call-template>
<xsl:value-of select="util:formatCurrency(rate,$language,$countryCode)" />
</fo:block>
</fo:block-container>
</fo:table-cell>
</xsl:for-each>