[XSL-LIST Mailing List Archive Home] [By Thread] [By Date] [Recent Entries] [Reply To This Message]

RE: [XSL] Counting Child Nodes?

Subject: RE: [XSL] Counting Child Nodes?
From: "Michael Kay" <mike@xxxxxxxxxxxx>
Date: Fri, 19 Oct 2007 16:02:20 +0100
RE:  [XSL] Counting Child Nodes?
>     <xsl:template match="book">
>         <xsl:variable name="rendition">
>             <xsl:value-of select="./@rendition"/>
>         </xsl:variable>

Use <xsl:variable name="rendition" select="@rendition"/>. It's shorter and
much more efficient.

>         <div>
>             <p>
>                <xsl:choose>
> 
>                     <xsl:when test="$rendition!=''">

Avoid !=. Use not($rendition = ''). The difference arises when $rendition is
an empty sequence.

>                         <div>
>                             <xsl:attribute name="class">
>                                 <xsl:value-of select="$rendition"/>
>                             </xsl:attribute>

Use <div class="{$rendition}">, unless you're paid by the number of lines of
code you write.

>                             <xsl:if
> test="string-length(child::text())&lt;'25'">

Don't put numbers in quotes. You can write this as
test="string-length(child::text()) &lt; 25". More importantly, I don't know
what you're trying to test. The context node is a <book> element, so its
first text node is the whitespace before the first <p>. I can't correct this
for you because I simply don't know what you intended. 

>                                 <xsl:attribute name="style"> 
> background-image:url('<xsl:value-of
>                                         
> select="./@rendition"/>.png') </xsl:attribute>
>                             </xsl:if>
>                             <xsl:if test="string-length('25 ' &lt;
> child::text() &lt; '50')">

The construct (25 < $x < 50) is no longer allowed in XSLT 2.0. The reason is
that although it's valid in 1.0, it doesn't mean what you think it means. If
$x is 10, for example, it evaluates (25 < 10) to false, and then evaluates
(false() < 50) which converts to (0 < 50) which is true. Write (25 < $x and
$x < 50).

But it hardly matters: test="string-length(EXPR)" where EXPR is a boolean
expression will always return true in 1.0 (in 2.0 it gives you a type error,
the argument must be a string). You meant

test="25 < string-length($x) and string-length($x) < 50)" 

>                                 <xsl:attribute name="style"> 
> background-image:url('<xsl:value-of
>                                         
> select="./@rendition"/>_med.png') </xsl:attribute>
>                             </xsl:if>
>                              <xsl:if test="count(child::p) &gt; 1">
>                                 <xsl:attribute name="style"> 
> background-image:url('<xsl:value-of
>                                         
> select="./@rendition"/>_large.png') </xsl:attribute>
>                             </xsl:if>

Rather than generating three attributes called style, of which all but the
last will be discarded, I would be inclined to use xsl:choose and only
generate one of them. In fact, I would put the conditional logic up front:

<xsl:variable name="png-suffix">
 <xsl:choose>
   <xsl:when test="..."/>
   <xsl:when test="...">_med</xsl:when>
   <xsl:when test="...">_large</xsl:when>
 </xsl:choose>
</xsl:variable>
<div class="{$rendition}"
style="background-image:url('{$rendition}{$png_suffix}.png')">


Having said all this, I don't know why your code isn't working, but I would
fix the above so you have something slightly more respectable to debug.

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


> 
>                             <p>
>                                 <xsl:call-template name="rend"/>
>                                 <xsl:apply-templates/>
>                             </p>
>                         </div>
>                     </xsl:when>
>                     <xsl:otherwise>
>                         <!--Don't display anything-->
>                     </xsl:otherwise>
>                 </xsl:choose>
>             </p>
>         </div>
>     </xsl:template>
> 
> XML:
> 
> <book topic="Technology" rendition="xslt" author="Tennison, Jeni" 
> title="Beginning XSLT">
> 
>     <p>New York: Apress, 2002.</p>
>     <p>The book serves as an introduction to XSLT based on 
> the examples of a television program set. A resourceful book 
> for those new to the technology.</p>
>   </book>
> 
> I want to use the code displayed above (XML) to display the 
> file name with the name of xslt_large, and now in the HTML 
> source it does not display that, even though the code above 
> has two <p> tags. Can anyone please help me out?
> 
> Anything is appreciated.
> 
> Alice

Current Thread

PURCHASE STYLUS STUDIO ONLINE TODAY!

Purchasing Stylus Studio from our online shop is Easy, Secure and Value Priced!

Buy Stylus Studio Now

Download The World's Best XML IDE!

Accelerate XML development with our award-winning XML IDE - Download a free trial today!

Don't miss another message! Subscribe to this list today.
Email
First Name
Last Name
Company
Subscribe in XML format
RSS 2.0
Atom 0.3
Site Map | Privacy Policy | Terms of Use | Trademarks
Free Stylus Studio XML Training:
W3C Member
Stylus Studio® and DataDirect XQuery ™are products from DataDirect Technologies, is a registered trademark of Progress Software Corporation, in the U.S. and other countries. © 2004-2011 All Rights Reserved.