XSLT - How to set correct language in a choos - xslt

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

Need xslt attribute to create/format table with only outer border , no column separating border

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>

Image not found for background-image attribute of block-container

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')" />

XSL stylesheet Using variables to calculate

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')"/> €

Force line break after string length

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>

setting up dynamic row height in xsl fo

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>