RE: [xsl] Finding the current node type

Subject: RE: [xsl] Finding the current node type
From: "Michael Kay" <mike@xxxxxxxxxxxx>
Date: Tue, 31 Jul 2007 09:25:05 +0100
This is exactly what apply-templates is for. Whenever you see code along the
lines

<xsl:choose>
  <xsl:when test="name()='foo'">

you should replace it by a call on apply-templates and a set of template
rules for the different branches, in a special mode if necessary.

Michael Kay
http://www.saxonica.com/ 


> -----Original Message-----
> From: Mark Anderson [mailto:mark.anderson@xxxxxxxxxxxxxxxxxxx] 
> Sent: 30 July 2007 23:35
> To: xsl-list@xxxxxxxxxxxxxxxxxxxxxx
> Subject: [xsl] Finding the current node type
> 
> Hi All
> 
> I'm trying to figure out a way to determine the "type" of the 
> current node in an nodeset.
> 
> I have a union of two dissimilar nodesets and I need to 
> number the combined set sequentially in my output. I also 
> need to output details from each node, but as they are 
> completely different I need to process each node type 
> differently based on it's contents.
> 
> Here's a silly example
> 
> <products>
> 	<speaker>
> 		<woofer>12 inch</woofer>
> 		<rms_power>70 watts</rms_power>
> 		<peak_power>95 watts</peak_power>
> 		<height>40 inches</height>
> 		<width>18 inches</width>
> 		<depth>18 inches</depth>
> 	</speaker>
> 	<laptop>
> 		<disk>80GB</disk>
> 		<screen>15 inch</screen>
> 		<cpu>Intel Core Duo 2.3ghz</cpu>
> 		<weight>5.2lbs</weight>
> 	</laptop>
> 	...
> </products>
> 
> So, I need to do something like:
> 
> <xsl:for-each select="speaker | laptop">
> 	<!-- Assign a sequential Number -->
> 	Item No: <xsl:value-of select="position()"/> <br />
> 	<!-- Now output item-specific details -->
> 	<xsl:choose>
> 		<xsl:when test="node = speaker">
> 			RMS Power: <xsl:value-of 
> select="rms_power"/> <br />
> 			Peak Power: <xsl:value-of select="peak_power"/>
> <br />	
> 		</xsl:when>
> 		<xsl:when test="node = laptop">
> 			Disk Drive: <xsl:value-of select="disk"/> <br />
> 			CPU: <xsl:value-of select="cpu"/> <br />
> 
> 		</xsl:when>	
> 	</xsl:choose>
> </xsl:for-each> 
> 
> So, what I need to figure out is the test in the when clause 
> to see which type of node I'm processing.
> 
> I could hack it with something like:
> 	
> <xsl:when test="count(rms_power) &gt; 0"> 
> 	<!-- Must be a speaker -->
> 	RMS Power: <xsl:value-of select="rms_power"/>
> 	Peak Power: <xsl:value-of select="peak_power"/>		
> </xsl:when>
> 
> However, it's messy and I have to find unique child nodes for 
> every product.
> 
> I'm sure there's a more elegant way
> 
> Can anyone help?
> 
> TIA
> 
> Mark

Current Thread