RE: [xsl] building a nodeset from selected nodes

Subject: RE: [xsl] building a nodeset from selected nodes
From: "Hall, Kurt" <khall@xxxxxxxxxxx>
Date: Thu, 5 Jul 2001 10:26:21 -0600
Thanks, but doesn't the instruction: 
	<xsl:for-each select="key('columns-by-name', column)">
get a node-set of columns where name=column?  I need an instruction
that can get a node-set of columns where name IN (col1, col2, ...).

Re: using an apply-templates: I don't think I can use it as a way to
generate my node-list which can then be passed to a call-template.
The problem I see is that if I separate the node-set generation
from my transformation of that node set, I've got to use a variable
to connect the two (which I can't do because I don't have access to 
the nodeset() extension).

On the other hand, if there was a way for the select clause to
issue a call-template or apply-template then I think it would
work, but I don't think xsl supports anything like that, does
it?  For example, the following would work *if* it was legal
xsl:
  <xsl:variable name="nodes" select="<xsl:call-template..."/>
or using for-each:
  <xsl:variable name="nodes" select="<xsl:for-each...col1> | 
                                     <xsl:for-each...col2>"/>
-kurt


-----Original Message-----
From: Wendell Piez [mailto:wapiez@xxxxxxxxxxxxxxxx]
Sent: Wednesday, July 04, 2001 12:01 PM
To: xsl-list@xxxxxxxxxxxxxxxxxxxxxx
Subject: Re: [xsl] building a nodeset from selected nodes


Kurt,

If I read you right, this is a classic case for keys. We use them so much 
for grouping that we forget what they do, really.

<xsl:key name="columns-by-name" match="table/column" use="name"/>

then, in a template (or for-each):

<xsl:template match="table/query">
   <xsl:for-each select="key('columns-by-name', column)">
   ...do what you're going to do for each table/column
      'called' by the query...
   </xsl:for-each>
</xsl:template>

Try it out. The select expression could also be in an xsl:apply-templates.

Hope that helps,
Wendell

At 07:52 PM 7/4/01, you wrote:
>As is often the case, I found a solution while preparing this post to
>ask for help.  I think there may be a simpler solution however (using
>XPATH/predicates?), plus I'd like to be able to encapsulate my solution
>in a call-template so I can reuse it.   (As a newby I'd appreciate
>any other recommendations on usage, robustness, performance, etc.).
>
>I'm trying to generate a node-set from my input where the selection
>is specified by a list of elements.  Complicating matters somewhat is that
>the company I'm consulting for is using an older version of xalan that
>doesn't
>appear to support the nodeset() extension.
>
>For example, given the input:
>
>         <table>
>            <column>
>               <name>A</name>
>               <type>int</type>
>            </column>
>            <column>
>               <name>B</name>
>               <type>long</type>
>            </column>
>            <column>
>               <name>C</name>
>               <type>double</type>
>            </column>
>            <column>
>               <name>D</name>
>               <type>string</type>
>            </column>
>            ...
>
>            <query>
>               <column>A</column>
>               <column>C</column>
>            </query>
>            <query>
>               <column>B</column>
>               <column>C</column>
>            <query>
>            ...
>         </table>
>
>When I process the "query" elements, I'd like to construct a node-set which
>contains
>only nodes 'A' and 'C' (and their children), do something with those nodes,
>then process
>the next "query" which contains 'B' and 'C'. etc.
>
>In psuedo-SQL, this would be like "SELECT * FROM nodes WHERE name IN ('A',
>'C')".
>
>Here's the xsl I've come up with so far:
>
>      ...
>      <xsl:for-each select="table/query">
>         <xsl:call-template name="get-column-nodes">
>             <xsl:with-param name="nodes" select="/.."/>     <!-- create an
>empty node-set -->
>             <xsl:with-param name="columns" select="column"/>
>         </xsl:call-template>
>         ... <!-- I'd like to have the node-set here -->
>      </xsl:for-each>
>      ...
>
><xsl:template name="get-column-nodes">
>     <xsl:param name="nodes"/>
>     <xsl:param name="columns"/>
>     <xsl:if test="$columns">
>         <xsl:variable name="col" select="$columns[1]"/>
>         <xsl:variable name="new" select="//table/column[name=$col]"/>
>         <xsl:variable name="newnodes" select="$nodes | $new"/>
>         <xsl:variable name="rest" select="$columns[position()!=1]"/>
>         <xsl:choose>
>         <xsl:when test="not($rest)">
>             DO SOMETHING WITH THESE NODES...
>             <xsl:for-each select="$newnodes">
>                 <xsl:value-of select="."/>
>             </xsl:for-each>
>             DONE
>         </xsl:when>
>         <xsl:otherwise>
>             <xsl:call-template name="get-column-nodes">
>                 <xsl:with-param name="nodes" select="$newnodes"/>
>                 <xsl:with-param name="columns" select="$rest"/>
>             </xsl:call-template>
>         </xsl:otherwise>
>         </xsl:choose>
>     </xsl:if>
></xsl:template>


======================================================================
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

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


Current Thread