Four replies to my query were rapid, courteous, succinct and helpful. Thank
you; I could only wish my integration of the solution into the project had been
as rapid.
I adopted the nested compound Muench solution suggested by J Pietschmann and
Mukul Ghandi, preferring it to the node-set() extension solution suggested by
Wendell Piez to allow for implementation independence. However, I shall eagerly
await the adoption and widespread implementation of XSLT 2.0.
Wendell Piez queried my decision to solve this problem in the stylesheet rather
than in the SQL query that originates this operation. My reason for doing so is
to make the query as generic as possible, avoiding the need for updates to
queries to follow extensions to the database, critical to the user's operation.
The XML file produced from the query is not critical and not sensitive in the
same way.
For interest, here is the template that I have installed:
<xsl:template name="User_Permissions">
<!-- A node set of the first occurrence of each property in br_props with a
user-id -->
<xsl:for-each
select="br_props/dbrow[generate-id(.)=generate-id(key('permissions-values',
concat(property,':',prvalue))[1])and number(user_id)!=0 and(prvalue='Yes' or
prvalue='No')]">
<xsl:sort select="property"/>
<xsl:sort select="prvalue" order="descending"/>
<table width="90%" border="1">
<!-- All permissions appear in order: permission; yes/no; user_id;
acct_id -->
<!-- Form table entries with header for permission - yes/no -->
<!-- col 1 is user name, col 2 is account names -->
<tr>
<th colspan="2">
<xsl:value-of select="property"/>
<xsl:text> - </xsl:text>
<xsl:value-of select="prvalue"/>
</th>
</tr>
<!-- Find all the individual users with this property and prvalue -->
<xsl:for-each
select="../dbrow[generate-id(.)=generate-id(key('permissions-values-users',concat(current()/property,':',current()/prvalue,':',user_id))[1])]">
<xsl:sort select="user_id" data-type="number"/>
<tr>
<td>
<xsl:choose>
<xsl:when test="">
<xsl:text>user_</xsl:text>
<xsl:value-of select="user_id"/>
</xsl:when>
<xsl:otherwise>
<xsl:element name="a">
<xsl:attribute name="href">
<xsl:text>#user_</xsl:text>
<xsl:value-of select="user_id"/>
</xsl:attribute>
<xsl:value-of select="key('user_ids', user_id)/username"/>
</xsl:element>
</xsl:otherwise>
</xsl:choose>
</td>
<td>
<!-- Find all the individual accounts with this property, prvalue
and user_id -->
<xsl:for-each
select="key('permissions-values-users',concat(property,':',prvalue,':',user_id))">
<xsl:sort select="acct_id" data-type="number"/>
<xsl:choose>
<xsl:when test="acct_id=0">-</xsl:when>
<xsl:when test="key('acct_ids', acct_id)/acct_num=0">
<xsl:text>acct_</xsl:text>
<xsl:value-of select="acct_id"/>
</xsl:when>
<xsl:otherwise>
<xsl:element name="a">
<xsl:attribute name="href">
<xsl:text>#acct_</xsl:text>
<xsl:value-of select="acct_id"/>
</xsl:attribute>
<xsl:value-of select="key('acct_ids', acct_id)/acct_num"/>
</xsl:element>
</xsl:otherwise>
</xsl:choose>
<xsl:if test="position()!=last()">, </xsl:if>
</xsl:for-each>
</td>
</tr>
</xsl:for-each>
</table>
</xsl:for-each>
</xsl:template>
Thank you again
John Marshall
Accurate Software
80 Peach Street, Wokingham, Berkshire, RG40 1XH, UK.
Tel: +44 (0)118 977 3889
Fax: +44 (0)118 977 1260
http://www.accuratesoftware.com <http://www.accuratesoftware.com>
-----Original Message-----
From: J.Pietschmann [mailto:j3322ptm(_at_)yahoo(_dot_)de]
Sent: 25 July 2003 17:56
To: xsl-list(_at_)lists(_dot_)mulberrytech(_dot_)com
Subject: Re: [xsl] Controlling tabular layout of a nodeset
John Marshall wrote:
I want to display it as:
+--------+------------------+
|property1 - prvalue1 |
+--------+------------------+
|user_id1|acct_id1, acct_id2|
+--------+------------------+
|user_id2|acct_id1 ... |
+--------+------------------+
Seems like a double grouping problem, first by property, then
by user_id. You need a composite key for the inner group.
Try something like
<xsl:key name="property" match="row" use="property"/>
<xsl:key name="user_id" match="row" use="
concat(property,':',user_id)"/>
<xsl:for-each select="row[generate-id() =
generate-id(key('property',property)[1])">
<tr>
<td><xsl:value-of select="property"/></td>
<td><xsl:value-of select="prvalue"/></td>
<tr>
<xsl:for-each select="key('property',property)[
generate-id()=generate-id(key('user_id',
concat(property,':',user_id))[1])">
<tr>
<td><xsl:value-of select="user_id"/></td>
<td>
<xsl:for-each select="key('user-id',
concat(property,':',user_id))">
<xsl:if test="position()!=last()>,</xsl:if>
</td>
</tr>
</xsl:for-each>
</xsl:for-each>
(caution: untested)
J.Pietschmann
XSL-List info and archive: http://www.mulberrytech.com/xsl/xsl-list
Accurate Software
info(_at_)accuratesoftware(_dot_)com
www.accuratesoftware.com
Europe . North America . Australasia . Africa
The information in this email is confidential and privileged and is intended
only for the use of the individual or entity listed above. If you are neither
the intended individual, or entity listed above, nor the person responsible for
the delivery of this email to the intended recipients, you are hereby notified
that any unauthorised distribution, copying or use of this email is prohibited.
If you have received this email in error, please notify the Accurate system
manager at postmaster(_at_)accuratesoftware(_dot_)com or on +44 (0)118 977
3889. The views expressed in this communication may not necessarily be the
views held by the Accurate Group.
XSL-List info and archive: http://www.mulberrytech.com/xsl/xsl-list