RE: [xsl] Selecting the first sentence of a paragraph

Subject: RE: [xsl] Selecting the first sentence of a paragraph
From: "Michael Kay" <mhk@xxxxxxxxx>
Date: Tue, 28 Oct 2003 08:26:00 -0000
Bite the bullet and use recursion. Something like this:

<xsl:template match="p">
  <p>
  <xsl:apply-templates select="child::node()[1]" mode="first"/>
  </p>
</xsl:template>

<xsl:template match="text()[contains(., '.')]" mode="first">
  <xsl:value-of select="substring-before(., '.')"/>
  <xsl:text>.</xsl:text>
</xsl:template>

<xsl:template match="*[contains(., '.')]" mode="first">
  <xsl:copy>
  <xsl:apply-templates select="child::node()[1]" mode="first"/>
  </xsl:copy>
</xsl:template>

<xsl:template match="node()" mode="first">
  <xsl:copy-of select="."/>
  <xsl:apply-templates select="following-sibling::node()[1]"
mode="first"/>
</xsl:template>

Michael Kay

> -----Original Message-----
> From: owner-xsl-list@xxxxxxxxxxxxxxxxxxxxxx 
> [mailto:owner-xsl-list@xxxxxxxxxxxxxxxxxxxxxx] On Behalf Of 
> Larry Kollar
> Sent: 28 October 2003 04:14
> To: xsl-list@xxxxxxxxxxxxxxxxxxxxxx
> Subject: [xsl] Selecting the first sentence of a paragraph
> 
> 
> Subject says it mostly, but I want to include any elements as well as 
> text nodes making up that first sentence.
> 
> Hm, maybe I'd better show a sample XML fragment:
> 
> <section>
>    <label>show exception</label>
>    <p>Syntax: <cmd>show exception <arg>n</arg></cmd></p>
>    <p>Identical to <keyword>systat</keyword>.
>    The optional argument <arg>n</arg> specifies the level of 
> detail.</p>
>    <other>stuff we don't care about</other>
> </section>
> 
> The part I have working pretty well applies the identity 
> transform to the first paragraph if it starts with "Syntax." 
> I also want to copy the first sentence of the next paragraph 
> (or the first sentence of the first paragraph if there's no 
> "Syntax" definition). The following template gets the first 
> sentence but removes the internal markup:
> 
> 	<xsl:template match="p" mode="firstsentence">
> 		<p><xsl:copy-of 
> select='concat(substring-before(.,"."), ".")' /></p>
> 	</xsl:template>
> 
> Producing "Identical to systat." That I expect, and set it up 
> as a placeholder until I could get what I really wanted. 
> That's been somewhat knottier.
> 
> I assume I'll have to use xsl:for-each to select all the 
> nodes up to the first period in the paragraph, apply the 
> identity transform to them, then select the node containing 
> the period and use the
> concat(substring-before(.,"."),".") function to get that part.
> 
> I've tried a couple of variations on
> xsl:for-each select='./*/preceding-sibling::*[contains(text(),".")]'
> which is probably causing hysterical laughter and/or retching 
> among some of you.... I'm probably making this harder than it 
> has to be.
> 
> Any suggestions are much appreciated. I'm using xsltproc if 
> that makes a difference.
> --
> Larry Kollar    k  o  l  l  a  r  @  a  l  l  t  e  l  .  n  e  t
> "The hardest part of all this is the part that requires thinking."
> -- Paul Tyson, on xml-doc 
> 
> 
>  XSL-List info and archive:  http://www.mulberrytech.com/xsl/xsl-list
> 


 XSL-List info and archive:  http://www.mulberrytech.com/xsl/xsl-list


Current Thread