Subject: Re: [xsl] Truncating output of a node From: Jeni Tennison <mail@xxxxxxxxxxxxxxxx> Date: Thu, 19 Apr 2001 23:17:40 +0100 |
Hi Jim, > I guess another possibility it to output n characters and add '...' > at the end to create the summary. Is that any easier? I can just tell everyone's dying for a patented Jeni solution to this problem. So here's my approach - step through the nodes one by one, keeping track of the number of sentences that have been output so far (as Mike suggested). Be careful, though - text nodes might hold more than one sentence, so you need to have some recursion over the string in there as well. So have one template for text nodes: <xsl:template match="text()" name="text"> <!-- $sentences holds the number of sentences covered so far --> <xsl:param name="sentences" select="0" /> <!-- $text holds the text of the text node (or portion of a text node when this template is called recursively --> <xsl:param name="text" select="." /> <!-- $next holds the next node to move on to --> <xsl:param name="next" select="following-sibling::*[1]" /> <xsl:choose> <!-- if this text contains a sentence delimiter... --> <xsl:when test="contains($text, '. ')"> <!-- ... finish the sentence ... --> <xsl:value-of select="substring-before($text, '. ')" /> <xsl:text>. </xsl:text> <!-- ... and if we've output less than 2 sentences before (i.e. we've not just finished the third) ... --> <xsl:if test="$sentences < 2"> <!-- ... call the template on the rest of the string ... --> <xsl:call-template name="text"> <!-- ... adding one to the sentences count --> <xsl:with-param name="sentences" select="$sentences + 1" /> <!-- ... passing the rest of the text node --> <xsl:with-param name="text" select="substring-after($text, '. ')" /> <!-- ... and keeping the same next node --> <xsl:with-param name="next" select="$next" /> </xsl:call-template> </xsl:if> </xsl:when> <xsl:otherwise> <!-- ... otherwise just give the value of the string ... --> <xsl:value-of select="$text" /> <!-- ... and apply templates to the following span element, keeping the number of sentences the same --> <xsl:apply-templates select="$next"> <xsl:with-param name="sentences" select="$sentences" /> </xsl:apply-templates> </xsl:otherwise> </xsl:choose> </xsl:template> Have another template for span elements, which can be a lot simpler, just basically applies templates to the next node, passing through the same count - this takes advantage of the fact that sentences never end within span elements: <xsl:template match="span"> <xsl:param name="sentences" select="0" /> <xsl:copy-of select="." /> <xsl:apply-templates select="following-sibling::node()[1]"> <xsl:with-param name="sentences" select="$sentences" /> </xsl:apply-templates> </xsl:template> Then you can start the process by just applying templates to the first node under the summary: <xsl:template match="summary"> <xsl:apply-templates select="node()[1]" /> </xsl:template> I hope that helps, Jeni --- Jeni Tennison http://www.jenitennison.com/ XSL-List info and archive: http://www.mulberrytech.com/xsl/xsl-list
Current Thread |
---|
|
<- Previous | Index | Next -> |
---|---|---|
RE: [xsl] Truncating output of a no, Jim Schmidt | Thread | RE: [xsl] Truncating output of a no, RSuiter |
Re: [xsl] Transitive closure for XP, Christian Nentwich | Date | RE: [xsl] Namespaces and XML -Resol, Nice, Kerry A. (LNG- |
Month |