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 |
---|
|
<- Previous | Index | Next -> |
---|---|---|
RE: [xsl] empty element as an end-m, Michael Kay | Thread | Re: [xsl] empty element as an end-m, Wendell Piez |
[xsl] xsl-fo: mixed page layout & c, Philip Fitzsimons | Date | Re: [xsl] xpath question, florian |
Month |