|
Subject: RE: [xsl] Grouping into a table (for vertical alignment) From: "Daniel Joshua" <daniel.joshua@xxxxxxxxxxxx> Date: Mon, 31 May 2004 11:43:41 +0800 |
>The trade-off is that walking the tree explicitly makes for more complex
>templates that work in what, to a newbie, is a highly unorthodox way
COMPLETED! Well just for the record, this is my "not so elegant" approach...
XML:
<form>
<name>loginForm</name>
<action>submit.do</action>
<method>post</method>
<content>
<text>
<value>Please login here...</value>
</text>
<input>
<name>userName</name>
<label>User Name</label>
<value></value>
</input>
<password>
<name>password</name>
<label>Password</label>
<value></value>
</password>
<check>
<name>stayLogin</name>
<label>Stay Logged In</label>
<value>true</value>
<selected>true</selected>
</check>
</content>
</form>
XSL:
<xsl:template match="form">
<form>
<xsl:for-each select="name | action | method">
<xsl:attribute name="{name()}">
<xsl:value-of select="."/>
</xsl:attribute>
</xsl:for-each>
<xsl:for-each select="content/*">
<xsl:call-template name="line"/>
</xsl:for-each>
</form>
</xsl:template>
<xsl:template name="line" match="line">
<xsl:choose>
<xsl:when test="not(self::info or self::input or self::password or
self::memo or self::check or self::radio or self::combo)">
<div class="line">
<xsl:apply-templates select="."/>
</div>
</xsl:when>
<xsl:when test="position() = 1 or not(preceding-sibling::info or
preceding-sibling::input or preceding-sibling::password or
preceding-sibling::memo or preceding-sibling::check or
preceding-sibling::radio or preceding-sibling::combo)">
<table>
<xsl:call-template name="lineInTable"/>
</table>
</xsl:when>
<!-- Otherwise ignore -->
</xsl:choose>
</xsl:template>
<xsl:template name="lineInTable">
<tr>
<xsl:apply-templates select="."/>
</tr>
<xsl:if test="following-sibling::info or following-sibling::input or
following-sibling::password or following-sibling::memo or
following-sibling::check or following-sibling::radio or
following-sibling::combo">
<xsl:for-each select="following-sibling::node()[1]">
<xsl:call-template name="lineInTable"/>
</xsl:for-each>
</xsl:if>
</xsl:template>
<xsl:template match="input">
<xsl:apply-templates select="label"/>
<td class="data">
<xsl:element name="input">
<xsl:attribute name="type">
<xsl:text>text</xsl:text>
</xsl:attribute>
<xsl:for-each select="name | value">
<xsl:attribute name="{name()}">
<xsl:value-of select="."/>
</xsl:attribute>
</xsl:for-each>
</xsl:element>
</td>
<xsl:apply-templates select="error"/>
</xsl:template>
<xsl:template match="label">
<td class="label">
<xsl:value-of select="."/>
<xsl:text>: </xsl:text>
</td>
</xsl:template>
<xsl:template match="error">
<td class="error">
<xsl:value-of select="."/>
</td>
</xsl:template>
Just a short comment, when using <xsl:call-template/> you cannot use a
"select="... really find that inconvienent.
Regards,
Daniel
-----Original Message-----
From: Wendell Piez [mailto:wapiez@xxxxxxxxxxxxxxxx]
Sent: Friday, 28 May, 2004 11:49 PM
To: xsl-list@xxxxxxxxxxxxxxxxxxxxxx
Subject: RE: [xsl] Grouping into a table (for vertical alignment)
Hi Daniel,
At 11:01 PM 5/27/2004, you wrote:
>Thanks Wendell... trying to figure it out now :p
>
> >Jeni works through one of these in entry 12 in the FAQ
> >page at http://www.dpawson.co.uk/xsl/sect2/N4486.html#d4726e727.
>
>Looking at it too, entry 12 actually allows me to handle my problem without
>a <xsl:key> ...
That's right: it's the other technique I mentioned: the "forward walk" or
"tree visitor". The key-based technique is just called "key-based
positional grouping" (since the nodes are grouped based on their relative
positions), although I like to call it "levitation".
The trade-off is that walking the tree explicitly makes for more complex
templates that work in what, to a newbie, is a highly unorthodox way, since
they use <xsl:apply-templates select="following-sibling::*[1]"
mode="walk"/> or the like. Using keys is a bit more elegant in the XSLT,
arguably, but lays the stress on that key declaration, whose XPath (as you
saw) can be ... "ornate", let's say.
>I got a question on entry 17:
>
> > <xsl:apply-templates mode="inGroup"
> > select="following-sibling::*[position() < $vGroupLength]"/>
>
>"vGroupLength" is the number of elements in the group.
>
>How does the "position()" work when used in the above manner,
>is it just the "context position" within (1) the node list of only
>"following-sibling"
>or (2) a node list of all siblings? I guess the first, but I just want to
>confirm.
You are correct, it's the node list of the following siblings. (The context
of a predicate is provided by the nodes and node-set the predicate operates
on.)
But you don't actually want this as it groups by a count -- first three
nodes, next three nodes, next three nodes -- or they could be in twelves or
nineteens: you get the idea. Whereas you need to group based on what nodes'
neighbors are (which is why your problem is a bit harder).
>I really appreciate all the help I am getting from this list. Thanks all.
Sure. You have a toughie, but it's been done. Digging in the archives for
"forward walk" or "tree visitor" would be a way to learn more about the
technique I did *not* explain (but which some say is easier: I dunno, if
you understand keys I think they're about the same).
Cheers,
Wendell
| Current Thread |
|---|
|
| <- Previous | Index | Next -> |
|---|---|---|
| RE: [xsl] Grouping into a table (fo, Wendell Piez | Thread | RE: [xsl] Grouping into a table (fo, Pieter Reint Siegers |
| Re: [xsl] Integrating HTML tidy wit, James Petry | Date | XSL extensions to use perl code, gustave loial |
| Month |