|
[XSL-LIST Mailing List Archive Home] [By Thread] [By Date] [Recent Entries] [Reply To This Message] Re: Using XSL to Translate Repetitive-Node XML to Tabl
Leo,
Looking at your data again, I see you have the harder case: At 03:49 PM 2/12/2004, you wrote: ...so things get trickier. Comparing this with the last template I posted: <xsl:template match="data"> <xsl:variable name="thisname" select="@name"/> <!-- first be sure we emit cells only for the first data element with a given name --> <xsl:if test="not($thisname = preceding-sibling::data/@name)"> <!-- the colspan is the count of data children of the parent with the same name --> <td colspan="{count(../data[@name = $thisname)}"> <xsl:apply-templates select="@name"/> <!-- the built-in default template for attributes will emit its value --> </td> </xsl:if> </xsl:template> There are two problems. First, we emit cells not for the first data element with a given @name, but for any data element that doesn't have an immediately preceding sibling with the same name. That's not so hard: <xsl:if test="not($thisname = preceding-sibling::data[1]/@name)"> The trickier bit is counting the following siblings with the same name that belong with this one. Really tricky, since the preceding-sibling and following-sibling axes look at *all* the siblings. Extra points to any XSLTer who can suggest how to do this count without a counter! (You're right, we don't like counters.) We can implement a counter as follows, using a recursive "tiptoe forward" technique: <xsl:template match="data" mode="gimme-count"> <xsl:parameter name="so-far" select="1"/> <xsl:choose> <xsl:when test="not(following-sibling::data[1]/@name = current()/@name)"> <!-- if our next data sibling doesn't have the same name, we're done --> <xsl:value-of select="$so-far"/> </xsl:when> <xsl:otherwise> <!-- if it does, we apply this same template to it, incrementing our counter --> <xsl:apply-templates select="following-sibling::data[1]" mode="gimme-count"> <xsl:with-param name="so-far" select="$so-far + 1"/> </xsl:apply-templates> </xsl:otherwise> </xsl:choose> </xsl:template> You would invoke this by binding it to a variable in your template matching the data element: <xsl:variable name="count"> <xsl:apply-templates select="." mode="gimme-count"/> </xsl:variable> so, all together: <xsl:template match="data"> <xsl:if test="not(@name = preceding-sibling::data[1]/@name)"> <xsl:variable name="count"> <xsl:apply-templates select="." mode="gimme-count"/> </xsl:variable> <td colspan="{$count}"> <xsl:apply-templates select="@name"/> <!-- the built-in default template for attributes will emit its value --> </td> </xsl:if> </xsl:template> Note: untested! I hope it works ... Cheers, Wendell ====================================================================== Wendell Piez mailto:wapiez@xxxxxxxxxxxxxxxx Mulberry Technologies, Inc. http://www.mulberrytech.com 17 West Jefferson Street Direct Phone: 301/315-9635 Suite 207 Phone: 301/315-9631 Rockville, MD 20850 Fax: 301/315-8285 ---------------------------------------------------------------------- Mulberry Technologies: A Consultancy Specializing in SGML and XML ====================================================================== XSL-List info and archive: http://www.mulberrytech.com/xsl/xsl-list
|
PURCHASE STYLUS STUDIO ONLINE TODAY!Purchasing Stylus Studio from our online shop is Easy, Secure and Value Priced! Download The World's Best XML IDE!Accelerate XML development with our award-winning XML IDE - Download a free trial today! Subscribe in XML format
|

Cart








