Reputation: 53
i need to find all the book and if the book has more than one author,write the first authors name and "et al" after that name.Below is my code and first book prints with "J.K. Rowling et al" but its not working for the second book.
this is the xml code
<bookstore>
<book>
<title category="fiction">Harry Potter</title>
<author>J. K. Rowling</author>
<author>sxdgfds</author>
<publisher>Bloomsbury</publisher>
<year>2005</year>
<price>29.99</price>
</book>
<book>
<title category="fiction">The Vampire Diaries</title>
<author>L.J. Smith</author>
<author>sdgsdgsdgdsg</author>
<publisher>Bloomsbury</publisher>
<year>2004</year>
<price>25.99</price>
</book>
<book>
<title category="fiction">The DaVinci Code</title>
<author>Dan Brown</author>
<publisher>Bloomsbury</publisher>
<year>2002</year>
<price>35.99</price>
</book>
this is the xslt code
<xsl:for-each select="//book[30 >price]">
<xsl:if test="title[@category='fiction']">
<span style="color:blue;font-weight:bold"><xsl:value-of select="title"/></span><br />
<xsl:choose>
<xsl:when test="count(./author)>1">
<span style="color:red;font-style:italic"><xsl:value-of select="author"/></span>
<span style="color:red;font-style:italic"> et al</span><br />
</xsl:when>
<xsl:otherwise>
<span style="color:red;font-style:italic"><xsl:value-of select="author"/></span><br />
</xsl:otherwise>
</xsl:choose>
<span><xsl:value-of select="price"/></span><br />
</xsl:if>
</xsl:for-each>
i was trying to count how many authors are there but seems like i'm having a problem with the path that i have given to the count function.Any help would be appreciated.
Upvotes: 0
Views: 496
Reputation: 338118
Your code seems to be okay, but the same thing can be expressed simpler.
<xsl:for-each select="//book[price < 30]">
<xsl:if test="title[@category='fiction']">
<span style="color:blue;font-weight:bold"><xsl:value-of select="title"/></span><br />
<span style="color:red;font-style:italic"><xsl:value-of select="author[1]" /></span>
<xsl:if test="author[2]">
<span style="color:red;font-style:italic"> et al</span>
</xsl:if>
<br />
<span><xsl:value-of select="price"/></span><br />
</xsl:if>
</xsl:for-each>
The above is shorter than your code, but it's not very elegant. This is better.
<xsl:template match="/">
<xsl:apply-templates select="//book[price < 30 and @category='fiction']" />
</xsl:template>
<xsl:template match="book">
<div class="book">
<div class="title"><xsl:value-of select="title"/></div>
<div class="author">
<xsl:value-of select="author[1]" /><xsl:if test="author[2]"> et al</xsl:if>
</div>
<div class="price"><xsl:value-of select="price"/></div>
</div>
</xsl:template>
<xsl:apply-templates>
instead of repeating yourself with <xsl:for-each>
.Upvotes: 1