Subject: RE: 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: 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
|