I am trying to implement FOP to output a PDF using XML and XSLT files.
My problem is the following I need to fix the position of words in a line (but not through using tables) for example:
I have the following xml:
<address>
<Line1 length="32" noLine="5" col="60" />
<Line2 length="32" noLine="6" col="60">Mr. John Kane</Line2 >
<Line3 length="32" noLine="7" col="60">15 Street Springfield</Line3 >
<Line4 length="32" noLine="8" col="60" />
<Line5 length="32" noLine="9" col="60" />
<Line6 length="6" noLine="10" col="60">75009</Line6 >
<Line7 length="25" noLine="10" col="67">Freesberg</Line7 >
<Line8 length="25" noLine="11" col="67">Idaho</Line8 >
</address>
length
is the word/sentence length noLine
is the line numbercol
is the beginning position of the word/sentence in the lineI did the lines but I can't seem to get to insert the word/sentence in the right position (col) in the line.
This is a part from my xslt:
<fo:block font-size="10" font-family="monospace">
<xsl:for-each select="*">
<xsl:variable name="currentNode" select ="name(.)"/>
<xsl:choose>
<xsl:when test="$currentNode = 'address'">
<xsl:for-each select="*">
<xsl:variable name="length" select ="@length"/>
<xsl:variable name="noLine" select ="@noLine"/>
<xsl:variable name="col" select ="@col"/>
<xsl:variable name="precNoLig" select = "preceding-sibling::*[1]/@noLine"/>
<xsl:choose>
<xsl:when test="$precNoLig = $noLine">
<fo:block font-size="10" font-family="monospace" text-indent="60">
 <xsl:value-of select="." />
</fo:block>
</xsl:when>
<xsl:otherwise>
<!--<fo:block font-size="10" font-family="monospace" >-->

<xsl:value-of select="." />
<!--</fo:block>-->
</xsl:otherwise>
</xsl:choose>
</xsl:for-each>
</xsl:when>
</xsl:choose>
</xsl:for-each>
</fo:block>
This is the expected output as PDF
:
Mr. John Kane
15 Street Springfield
75009 Freesberg
Idaho
Where it has the following positions in the PDF
(col):
<-----------------60-------------------->
<-----------------60-------------------->Mr. John Kane
<-----------------60-------------------->15 Street Springfield
<-----------------60-------------------->
<-----------------60-------------------->
<-----------------60-------------------->75009 Freesberg
<-----------------67-------------------------->Idaho
Any help would be appreciated.
It's a little convoluted, but this should work:
<?xml version="1.0" encoding="utf-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:strip-space elements="*" />
<xsl:output method="text"/>
<xsl:variable name="sp" select="' '" />
<xsl:template match="address/*">
<xsl:variable name="value">
<xsl:value-of select="." />
<xsl:if test="following-sibling::*[1]/@noLine = @noLine">
<xsl:value-of select="$sp" />
</xsl:if>
</xsl:variable>
<xsl:choose>
<xsl:when test="preceding-sibling::*[1]/@noLine = @noLine">
<xsl:variable name="col" select="preceding-sibling::*[1]/@col + preceding-sibling::*[1]/@length" />
<xsl:value-of select="concat(substring($sp,1,@col - $col),substring($value,1,@length))" />
</xsl:when>
<xsl:otherwise>
<xsl:if test="preceding-sibling::*"><xsl:text> </xsl:text></xsl:if>
<xsl:value-of select="concat(substring($sp,1,@col),substring($value,1,@length))" />
</xsl:otherwise>
</xsl:choose>
</xsl:template>
</xsl:stylesheet>
For this transform to work as-is, it's critical that your Line..
elements are in noLine
/col
order, as it bases how to pad it out on the previous element. If they're out of order it'll get it badly wrong.
The sp
variable must contain at least as many spaces as you'll ever need to pad it out to, i.e. the max value of any length
or col
attribute. This solution doesn't include spaces at the end of a line- it's actually easier to pad out each line with trailing spaces so that it fills the length given, but I assumed it would probably be preferable not to.
I've only tried it with the sample given, if it doesn't work for any other input you've got, let me know and I'll see if I can adapt it.
EDIT: I just noticed that you needed it in PDF format, sorry. I just looked at the output, and didn't notice the format. Hopefully you can adapt this to the format you need (It's actually quite similar to what you'd already tried), but if not, I'd suggest you manually create a PDF that represents your output and add the XML for that PDF to your question.