This is the mail archive of the
xsl-list@mulberrytech.com
mailing list .
problem with position() function
- To: XSL-List at mulberrytech dot com
- Subject: problem with position() function
- From: andreg at attglobal dot net
- Date: Thu, 13 Jul 2000 21:17:41 -0500
- Reply-To: xsl-list at mulberrytech dot com
I am trying to get a stylesheet to work to do some kind of databinding.
I have a <table> element in my input document, which declares one
prototype row. I also have the actual data in the input document, in my
stylesheet I try to create rows for all items I have in my model. I have
it almost working, just this last problem is driving me crazy, so I
wonder if anyone can tell me if there is a bug or if I am doing
something wrong. The sources are fairly long, and I apologize, but I
need to post it all to show the problem.
Here is the input document:
-----------------------------------------------------------------
<?xml version="1.0"?>
<doc>
<table>
<row>
<cell><input id="entry1"/></cell>
<cell><input id="entry2"/></cell>
<cell><input id="entry3"/></cell>
</row>
</table>
<items>
<item>
<entry1>Entry 1 Value 1</entry1>
<entry2>Entry 2 Value 1</entry2>
<entry3>Entry 3 Value 1</entry3>
</item>
<item>
<entry1>Entry 1 Value 2</entry1>
<entry2>Entry 2 Value 2</entry2>
<entry3>Entry 3 Value 2</entry3>
</item>
</items>
</doc>
-------------------------------------------------------------
The "id attribute for the input element matches the element name of the
entry in the items list. Here is the stylesheet that I am using:
-----------------------------------------------------------------
<?xml version='1.0'?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
version="1.0">
<xsl:output method="html" indent="yes"/>
<xsl:template match="* | @*">
<xsl:copy><xsl:copy-of select="@*"/><xsl:apply-templates/></xsl:copy>
</xsl:template>
<!-- process table -->
<!-- handle the rows -->
<xsl:template match="row">
<xsl:call-template name="processRow">
<xsl:with-param name="numItems"><xsl:value-of
select="count(//item)"/></xsl:with-param>
<xsl:with-param name="n">1</xsl:with-param>
</xsl:call-template>
</xsl:template>
<!-- handle all rows recursively for as many times as we have items -->
<xsl:template name="processRow">
<xsl:param name="numItems"/>
<xsl:param name="n"/>
<!-- first check if the loop ended -->
<xsl:if test="$numItems >= $n">
<xsl:copy>
<!-- handle all cells -->
<xsl:for-each select="cell">
<!-- copy the content of the cell, including attributes -->
<xsl:copy><xsl:copy-of select="@*"/>
<!-- find the elements that have an id attribute -->
<xsl:for-each select="./*[@id]">
<!-- need to assign a variable to the attribute value,
otherwise it will not work at all -->
<xsl:param name="elname"><xsl:value-of
select="./@id"/></xsl:param>
<xsl:copy><xsl:copy-of select="@*"/>
<!-- insert the value of the cell -->
<!-- this is the statement that causes trouble!! -->
<xsl:value-of select="//*[(name() = $elname) and
(parent::node()[position() = $n])]"/>
</xsl:copy>
</xsl:for-each>
</xsl:copy>
</xsl:for-each>
</xsl:copy>
<!-- now make the recursive call, increase n by 1 -->
<xsl:call-template name="processRow">
<xsl:with-param name="n">
<xsl:value-of select="$n + 1"/>
</xsl:with-param>
<xsl:with-param name="numItems">
<xsl:value-of select="$numItems"/>
</xsl:with-param>
</xsl:call-template>
</xsl:if>
</xsl:template>
<xsl:template match="doc">
<xsl:apply-templates/>
</xsl:template>
<xsl:template match="items"/>
</xsl:stylesheet>
----------------------------------------------------------------------
I am using Xalan 1.1. Here is the output it produces, which shows what
the problem is:
-------------------------------------------------------------------------
<table>
<row>
<cell>
<input id="entry1">Entry 1 Value 1</input>
</cell>
<cell>
<input id="entry2">Entry 2 Value 1</input>
</cell>
<cell>
<input id="entry3">Entry 3 Value 1</input>
</cell>
</row>
<row>
<cell>
<input id="entry1">
</cell>
<cell>
<input id="entry2">
</cell>
<cell>
<input id="entry3">
</cell>
</row>
</table>
----------------------------------------------------------------
It only finds the entries in the first <item> element. The way I try to
find these entries is by using "parent::node()[position() = $n]", but
that does not seem to work. Am I overlooking something here? Is there a
better way to do what I try to do?
Thanks a lot in advance,
Andre
XSL-List info and archive: http://www.mulberrytech.com/xsl/xsl-list