Subject: Re: [xsl] Referencing nodes from an out-of-scope xsl:for-each loop From: "Joel P Thornton" <joelt@xxxxxxxxxxxxx> Date: Fri, 18 May 2001 10:57:18 -0700 |
Adam Turoff wrote: --- [excellent solution here] (I suppose you could do the same thing matching on <row> with a lot of ancestor hacking, but I only thought of that after I got this pair of templates working.) Z. --- Adam - Thanks for your thoughtful response. It still isn't quite there yet, though; when you mentioned the <B> style information within the <column> tags being a problem, you were right. I gave this as a relatively simple example of what I'm hoping to achieve: <display-columns> <column label="Name"><B><sql-field name="title"/></B></column> <column label="Location"><sql-field name="location"/></column> </display-columns> But I am really wanting to do more complex stuff, such as this: <display-columns> <column label="Name"> <link> <label> <B><sql-field name="title"/></B> </label> <href> /viewarea.asp?where=<sql-field name="location"/> </href> </link> </column> </display-columns> .. in this way permitting versatile display formatting options while minimizing xsl work. Can this be done? I'd love to hear suggestions .. and thanks for those so far :) joel ======================================= --------------------------------------- > I have this xml: > > -- > <sql-recordset> > <row title="Sunshine Home" location="Seattle WA"/> > <row title="Value Village" location="Seattle WA"/> > <row title="Salvation Army" location="Tacoma WA"/> > > <display-columns> > <column label="Name"><B><sql-field name="title"/></B></column> > <column label="Location"><sql-field name="location"/></column> > </display-columns> > </sql-recordset> > -- > > And I want to write an XSL which will transform this into: > > -- > <table> > <th>Name</th> > <th>Location</th> > > <tr> > <td><b>Sunshine Home</b></td><td>Seattle WA</td> > </tr> ... > </table> > -- > > > Currently, I <xsl:for-each> through the collection of <row> nodes, and then > <xsl:for-each> through each of the <column>s for each row. The problem is, > I have a <xsl:template match="sql-field"> template which matches the > <sql-field> tags within the <column> tags. But I don't know how to get that > template to "know" which row it is currently on. I tried using > <xsl:variable> but I'm being told that, within the sql-field template, the > variable is out of scope. > > Ideas? First you need to get into a state where you have the tree fragment of rows as well as the tree fragment of columns. This can be done using <xsl:call-template> for <row>, passing a tree fragment for <display-columns> as a parameter. Once you've cracked that nut, it's a simple case of referring to both nodesets at the same time. :-) The really tricky part is respecting the bolding with <column label="Name"><B><sql-field name="title"/></B></column> as well as no formatting <column label="Location"><sql-field name="location"/></column> It took some trickery to get that working. You should consider a different way for specifying HTML styles to be output, such as putting a style='' attribute on <column> and passing it through to <td>. <xsl:template match="sql-recordset"> <xsl:variable name="display-columns" select="display-columns"/> <!-- table header (simple) --> <table> <tr> <xsl:for-each select="display-columns/column/@label"> <th><xsl:value-of select="."/></th> </xsl:for-each> </tr> <!-- table rows (passing the display format as a parameter --> <xsl:for-each select="row"> <xsl:call-template name="display-row"> <xsl:with-param name="display-columns" select="$display-columns"/> </xsl:call-template> </xsl:for-each> </table> </xsl:template> <!-- Emit the current <row/> as specified --> <xsl:template name="display-row"> <xsl:param name="display-columns"/> <!-- save the tree fragment for the row we're processing --> <xsl:variable name="row" select="."/> <tr> <!-- now loop over the column display order --> <xsl:for-each select="$display-columns/column//sql-field"> <xsl:variable name="column" select="@name"/> <td> <!-- HACK: Respect <b> surrounding <sql-field> --> <xsl:choose> <xsl:when test="name(..) != 'column'"> <xsl:element name="{name(..)}"> <xsl:value-of select="$row/attribute::*[name()=$column]"/> </xsl:element> </xsl:when> <xsl:otherwise> <!-- standard case: just emit the data --> <xsl:value-of select="$row/attribute::*[name()=$column]"/> </xsl:otherwise> </xsl:choose> </td> </xsl:for-each> </tr> </xsl:template> (I suppose you could do the same thing matching on <row> with a lot of ancestor hacking, but I only thought of that after I got this pair of templates working.) Z. --------------------------------------- ======================================= XSL-List info and archive: http://www.mulberrytech.com/xsl/xsl-list
Current Thread |
---|
|
<- Previous | Index | Next -> |
---|---|---|
Re: [xsl] Referencing nodes from an, Jeni Tennison | Thread | Re: [xsl] Referencing nodes from an, Adam Turoff |
[xsl] form example, Alex Black | Date | [xsl] Using accented characters in , Mike McGraw |
Month |