Altova Mailing List Archives

RE: [xsl] [XSL] Counting Child Nodes?

From: "Michael Kay" <mike@------------>
Date: 10/19/2007 3:03:00 PM
>     <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:when test="..."/>
   <xsl:when test="...">_med</xsl:when>
   <xsl:when test="...">_large</xsl:when>
<div class="{$rendition}"

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

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


These Archives are provided for informational purposes only and have been generated directly from the Altova mailing list archive system and are comprised of the lists set forth on Therefore, Altova does not warrant or guarantee the accuracy, reliability, completeness, usefulness, non-infringement of intellectual property rights, or quality of any content on the Altova Mailing List Archive(s), regardless of who originates that content. You expressly understand and agree that you bear all risks associated with using or relying on that content. Altova will not be liable or responsible in any way for any content posted including, but not limited to, any errors or omissions in content, or for any losses or damage of any kind incurred as a result of the use of or reliance on any content. This disclaimer and limitation on liability is in addition to the disclaimers and limitations contained in the Website Terms of Use and elsewhere on the site.