[xsl] Formatting XSL-FO Based on XML Position

Subject: [xsl] Formatting XSL-FO Based on XML Position
From: "Kyle Partridge" <kpartridge@xxxxxxxxxxxx>
Date: Mon, 15 Dec 2003 16:50:34 -0500
Experts,

Pardon the repetition, but apparently my previous format was not as
appropriate as it ought to have been.

Problem:
Create fo:table to format some text occurring after a fo:block.  The XML
input looks like this:

<p tabs="0.2 1.2 2.2">
some text, maybe formatted <b>maybe not</b>, and then:
<tab/>item<tab/>item2<tab/>item3<br/>
<tab/>item4<tab/>item5
</p>

The XSLT I have now for the tab formatting looks like this.  I know it
isn't very good, but I'm not very good at this.  Putting opening tags in
the first xsl:if, and closing tags in a later one does not work - but I
don't know what to do instead ?

<xsl:template match="ws:tab">
	<xsl:if test="position()=1">
		<fo:table>
			<fo:table-body>
				<fo:table-row>
	</xsl:if>
				
	<xsl:element name="fo:table-cell">
		<!-- I know this won't work, see below. -->
		<xsl:attribute name="width">
			<xsl:call-template name="get-width">
				<xsl:with-param name="list">
					<xsl:choose>
						<xsl:when
test="../@tabs">
	
<xsl:value-of select="../@tabs"/>
						</xsl:when>
						<xsl:otherwise>
						There is a way to get
alternative formatting information that goes here. No need to include it
- not relevant.
						</xsl:otherwise>
					</xsl:choose>
				</xsl:with-param>
				<xsl:with-param name="curpos">
					<xsl:choose>
						<xsl:when
test="preceding-sibling::ws:br">
	
<xsl:value-of select="count(../ws:tab)-position()"/>
						</xsl:when>
						<xsl:otherwise>
	
<xsl:value-of select="position()"/>
						</xsl:otherwise>
					</xsl:choose>
				</xsl:with-param>
			</xsl:call-template>
		</xsl:attribute>
	</xsl:element>
	<fo:block/>
	<xsl:element name="fo:table-cell">
		<fo:block><xsl:apply-templates/></fo:block>
	</xsl:element>
				
	<xsl:if test="position()=../ws:tab[last()]">
				</fo:table-row>
			</fo:table-body>
		</fo:table>
	</xsl:if>		
</xsl:template>


<xsl:template name="get-width">
	<xsl:param name="list"/>
	<xsl:param name="curpos"/>
	<xsl:variable name="nlist"
select="concat(normalize-space($list), ' ')"/>
	<xsl:variable name="first" select="substring-before($nlist, '
')"/>
	<xsl:choose>
		<xsl:when test="$curpos=1">
			<xsl:value-of select="$first"/>
		</xsl:when>
		<xsl:otherwise>
			<!--want list[curpos] - list[curpos-1]...I
think.  But how???-->
		</xsl:otherwise>
	</xsl:choose>
</xsl:template>

Obviously, I don't know what I'm doing here. I know I'm supposed to use
fo:table-column to give width information, but I can't see how I can do
that for only columns 1, 3, and 5...especially when I don't really know
how many columns there will be.  In this case, there are 6, but there
could be anywhere from 1-6. 

In the second template, get-width, if curpos(tab) is 1, then I can just
output the first string. But I can't come up with a way to properly
output the rest of the items.  If curpos is 2 or 3, or 4 or whatever, I
want the tab width output to be list[curpos] - list[curpos-1] but I
don't know how to express that here.  

Ultimately, the hope was to come out with something like:

<fo:table>
	<fo:table-column column-number="1" column-width="0.2pt">...???
etc
	<fo:table-row>
		<fo:table-cell><fo:block/></fo:table-cell>
		<fo:table-cell><fo:block>item</fo:block></fo:table-cell>
		<fo:table-cell><fo:block/></fo:table-cell>
	
<fo:table-cell><fo:block>item2</fo:block></fo:table-cell>
		<fo:table-cell><fo:block/></fo:table-cell>
	
<fo:table-cell><fo:block>item3</fo:block></fo:table-cell>
	</fo:table-row>
</fo:table>

Humbly...
KP


 XSL-List info and archive:  http://www.mulberrytech.com/xsl/xsl-list


Current Thread