[XSL-LIST Mailing List Archive Home] [By Thread] [By Date]

[xsl] Generating a 2 column table from only _some_ of the nodes.


Subject: [xsl] Generating a 2 column table from only _some_ of the nodes.
From: Martin Buchan <martinb@xxxxxxx>
Date: Fri, 14 Nov 2003 11:20:42 +0000

Hi,

Could anyone help me out with this. I have looked through the table generation stuff on the site but I think my problem is slightly different.

I need to build a 2 column table from only some of the nodes in my node set. Here is an excerpt from my XML.

<archive id="111111">
  <product label="Product" group="1. Product" required="t">aaa</product>
  <title label="Title" group="1. Product" required="t">bbb</title>
  <client label="Client" group="1. Product" required="t">ccc</client>
  <brand label="Brand" group="1. Product" required="t">ddd</brand>
  <jobref label="Job Reference" group="2. TV" required="f">eee</jobref>
  <tape_no label="Tape Number" group="2. TV" required="f">fff</tape_no>
  <duration label="Duration" group="2. TV" required="t">ggg</duration>
  <agency label="Agency" group="3. Agency" required="t">hhh</agency>
  <producer label="Producer" group="3. Agency" required="t">i</producer>
  <director label="Director" group="3. Agency" required="f">j</director>
</archive>

I dont know the element names in advance and I dont know how many elements there will be. Also, I need to lay them out in groups. I.e. I start a table for group "1. Product", lay out all the rows, finish the table and start a new table for group "2. TV" etc.

I was doing this initially using a key to select all elements in a group and the looping thru them with a for-each and using position() mod 2 = 1 and following-sibling::*[1] to lay out the first and second td.

This worked fine but now I need to only pick elements where @required = 'f'. This causes problems with following-sibling because there is no gaurantee that the following-sibling will have @required = 'f'. I can test for this but if it doesnt, then all i can do is layout an empty cell - which I dont want. What I want is someway to move forward int eh loop sort of.

Or, I want to build a new nodeset where @required = 'f'. I thought i was doing this with a key which had @required = 'f' in the predicate but It doesnt actually select only those nodes. It is selecing all the nodes.

Here is my key.

<xsl:key name="notreq1" match="/archive[1]/*[@required = 'f']" use="@group" />

Here is my current for loop.

<xsl:for-each select="/archive/*[count(. | key('notreq1', @group)[1]) = 1]">

<xsl:if test="not(@required = 't'">
<table width="100%" align="center" border="0">
<tr><td>
<xsl:value-of select="substring-after(../*[@group = current()/@group]/@group, '. ')"/>
</td></tr>
<xsl:for-each select="key('notreq1', @group)[@required = 'f'][not(position() = 0)]">
<xsl:sort select="@group" />
<xsl:when test="(position() mod 2) = 1">
<td><xsl:value-of select="."/></td>
<xsl:choose>
<xsl:when test="following-sibling::*[1]/@group = @group">
<xsl:with-param name="content" select="following-sibling::*[1]"/>
</xsl:when>
<xsl:otherwise>
<td>EMPTY CELL</td>
</xsl:otherwise>
</xsl:choose>
</xsl:if>
</xsl:for-each>
</xsl:if>
</xsl:for-each>



Can anyone see what I am trying to do?
Basically, my problem is with the node set i am looping through. Is there some way I can loop through only nodes with @required = 'f'. I thought the key did this. I.e. I thought I could build a new node set with the key???


I will provide more info if needed. I am in very new territory here so any help would be muchly appreciated.

Thanks

Martin



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



Current Thread