Re: [xsl] empty element as an end-marker

Subject: Re: [xsl] empty element as an end-marker
From: "Vincent Neyt" <vincent.neyts@xxxxxxxxxx>
Date: Fri, 28 Mar 2003 11:47:14 +0100
Thanks a lot,

the last recursive one works great!

cheers,
Vincent

----- Original Message ----- 
From: "Michael Kay" <mhk@xxxxxxxxx>
To: <xsl-list@xxxxxxxxxxxxxxxxxxxxxx>
Sent: Friday, March 28, 2003 10:41 AM
Subject: RE: [xsl] empty element as an end-marker


> These problems are slightly tricky, and the exact details of the
> solution depend on the exact nature of the problem.
> 
> A typical example of the problem is to convert
> 
> <p>
> line1<br/>
> line2<br/>
> linen
> </p>
> 
> to
> 
> <p>
> <line>line1</line>
> <line>line2</line>
> <line>linen</line>
> </p>
> 
> The best way to tackle this, provided that it doesn't exceed the
> recusion depth allowed by most processors (say 1000), is to use
> apply-templates recursing along the following-sibling axis. In simple
> cases the following works:
> 
> <xsl:template match="p">
> <p>
>   <xsl:apply-templates select="child::text()[1]" mode="along"/>
> </p>
> </xsl:template>
> 
> <xsl:template match="text()" mode="along">
> <line><xsl:value-of select="."/></line>
> <xsl:apply-templates select="following-sibling::text()[1]"
> mode="along"/>
> </xsl:template>
> 
> Unfortunately this isn't very robust. Some processors (wrongly) split
> text nodes when entity references are encountered, and all (rightly)
> split them when comments are encountered; also your text might have
> other elements such as <i> embedded in it.
> 
> So a more robust technique is to match the br elements, and each time
> you hit a br, copy all the preceding siblings whose next br element is
> this one. This can be done as follows:
> 
> <xsl:template match="br" mode="along">
> <xsl:copy-of select="preceding-sibling::node()
>     [generate-id(following-sibling::br[1])=generate-id(current())]"/>
> <xsl:apply-templates select="following-sibling::br[1]"/>
> </xsl:template>
> 
> Then you have to mop up the last group of elements (the ones that have
> no following br element) which you can do in the parent template.
> 
> This has O(n^n) performance and it can recurse deeply, so it isn't
> ideal. A more efficient solution is to treat it as a grouping problem.
> The sibling elements between two br elements constitute a group, the
> grouping key for this group is the generate-id() of the most recent br
> (or p) element. So you can use Muenchian grouping with the grouping key:
> 
> <xsl:key name="k" match="p/node()" 
> use="concat(generate-id(..), generate-id(preceding-sibling::br[1]"/>
> 
> It's easier in XSLT 2.0. If you can use Saxon 7.4, try:
> 
> <xsl:for-each-group select="child::node()" group-starting-with="br">
> <line><xsl:copy-of select="current-group()"/></line>
> </xsl:for-each-group>
> 
> Michael Kay
> Software AG
> home: Michael.H.Kay@xxxxxxxxxxxx
> work: Michael.Kay@xxxxxxxxxxxxxx 
> 
> 
> 
> > -----Original Message-----
> > From: owner-xsl-list@xxxxxxxxxxxxxxxxxxxxxx 
> > [mailto:owner-xsl-list@xxxxxxxxxxxxxxxxxxxxxx] On Behalf Of 
> > Vincent Neyt
> > Sent: 28 March 2003 00:09
> > To: XSL-List@xxxxxxxxxxxxxxxxxxxxxx
> > Subject: [xsl] empty element as an end-marker
> > 
> > 
> > Hello,
> > 
> > my problem is easily explained. This is the simple xml:
> > 
> > <p>some text some text <pb/>more text more text</p>
> > 
> > In my (html) output I need to process and reproduce the 'some 
> > text' (ie. up to the <pb/>) without the 'more text'. (Of 
> > course I also need to output just the 'more text' in another 
> > instance.) I'm having some trouble with this. Also the 'some 
> > text' contains tags which need to be processed by the stylesheet.
> > 
> > Sorry if this problem has been solved before, I searched the 
> > archives and FAQ's using 'empty elements' and didn't find 
> > anything. Thanx in advance, Vincent
> > 
> > 
> > 
> >  XSL-List info and archive:  http://www.mulberrytech.com/xsl/xsl-list
> > 
> 
> 
>  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