Subject: Re: [xsl] Move elements to preceding parent From: Israel Viente <israel.viente@xxxxxxxxx> Date: Wed, 17 Jun 2009 23:11:50 +0300 |
Hi Ken, I really appreciate your code and comments, but after reading it many times, I can't reach to the bottom of the logic here. I'm a newbie so forgive my stupid questions. 1. Why do we need the outer most copy element: > <xsl:template match="body"> > <xsl:copy> How does it work in combination with xsl:for-each-group? 2. Can you please explain the group-ending-with selection? Why do we need *[not(self::p)] ? Doesn't it mean all except p elements? Thanks, Viente On Sun, Jun 14, 2009 at 6:39 PM, G. Ken Holman<gkholman@xxxxxxxxxxxxxxxxxxxx> wrote: > At 2009-06-14 17:53 +0300, Israel Viente wrote: >> >> I am working with Saxon-B9.1 on the command line (XSLT 1.0 or 2.0 are OK). >> >> My input is something like the following: >> ... >> The reault output should be: > > Thank you for supplying complete examples to make the job of helping easier. > >> For every span element that the class<>'chapter' verify that in every >> p the last span element text ends with one character of .?"! >> (paragraph ending char). >> If it does, copy as is to the output. >> Otherwise: Move the span elements from the next p to the current one >> and remove the next p completely. >> >> I tried doing it with following-sibling & for-each , but I'm not sure >> it is the right approach. > > That wasn't the approach that came to mind immediately for me. I've learned > over the years that the reach of following-sibling is usually too extensive > to help out in many algorithms. > > With the advent of XSLT 2.0 what comes to mind immediately for me for such > cases is grouping. And I think it fits well here, though I am a bit > concerned your requirement may be under-specified. Certainly I could > rewrite your requirement by considering where paragraphs need to be > considered part of the same group when the span movement you need is being > triggered. > > The code below groups all of the elements of interest such that the group > always ends in a paragraph with the desired punctuation. Then I simply copy > the first as is and the spans and paragraph white-space of the others. I > didn't know what to do with the NBSP characters of the others and you only > said spans, so I only copied the white-space. Given this is paragraph > content between the spans, perhaps all text nodes should be preserved and > not just indentation. If so, just take the predicate off of the text() > address. > > I hope this shows how to look at your problem as a grouping problem. > > . . . . . . . . . . Ken > > > T:\ftemp>type viente.xml > <?xml version="1.0" encoding="UTF-8"?> > <!DOCTYPE html [<!ENTITY nbsp " ">]> > <html xmlns="http://www.w3.org/1999/xhtml"> > <body> > <p dir="rtl"> > <span class="chapter">line1</span> > </p> > <p dir="rtl"> <br /> > <span class="regular">line3.</span> > <span class="italic">line4</span> > <span class="regular">line5."</span> > </p> > <p dir="rtl"> <br /> > <span class="regular">line6.</span> > <br /> > <span class="regular">line7</span> > </p> > <p dir="rtl"> <br /> > <span class="regular">line8.</span> > <span class="regular">line9.</span> > </p> > </body> > </html> > > T:\ftemp>call xslt2 viente.xml viente.xsl > <?xml version="1.0" encoding="UTF-8"?><html > xmlns="http://www.w3.org/1999/xhtml"> > <body><p dir="rtl"> > <span class="chapter">line1</span> > </p><p dir="rtl">B B <br /> > <span class="regular">line3.</span> > <span class="italic">line4</span> > <span class="regular">line5."</span> > </p><p dir="rtl">B B <br /> > <span class="regular">line6.</span> > <br /> > <span class="regular">line7</span> > > <span class="regular">line8.</span> > <span class="regular">line9.</span> > </p></body> > </html> > T:\ftemp>type viente.xsl > <?xml version="1.0" encoding="US-ASCII"?> > <xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" > xpath-default-namespace="http://www.w3.org/1999/xhtml" > version="2.0"> > > <xsl:output indent="no"/> > > <xsl:template match="body"> > <xsl:copy> > <xsl:copy-of select="@*"/> > <xsl:for-each-group select="*" > group-ending-with="*[not(self::p)] | > p[span/@class='chapter'] | > p[matches(span[last()], > '[.?"]$')]"> > <!--now the information is grouped by p elements that end as > required--> > <xsl:choose> > <xsl:when test="current-group()[last()] > [self::p][matches(span[last()],'[.?"]$')]"> > <!--in a group of p elements that end as required--> > <xsl:copy> > <xsl:copy-of select="@*"/> > <!--preserve the content of the first of these p elements--> > <xsl:apply-templates/> > <!--preserve only the span elements and indentation from the > rest; > (the indentation is needed because this is paragraph > white-space)--> > <xsl:apply-templates select="current-group()[position()>1]/ > (text()[not(normalize-space())] | > span)"/> > </xsl:copy> > </xsl:when> > <xsl:otherwise> > <!--in another kind of group so just copy these using identity--> > <xsl:apply-templates select="current-group()"/> > </xsl:otherwise> > </xsl:choose> > </xsl:for-each-group> > </xsl:copy> > </xsl:template> > > <xsl:template match="@*|node()"><!--identity for all other nodes--> > <xsl:copy> > <xsl:apply-templates select="@*|node()"/> > </xsl:copy> > </xsl:template> > > </xsl:stylesheet> > > T:\ftemp>rem Done! > > > > -- > XSLT/XSL-FO/XQuery hands-on training - Los Angeles, USA 2009-06-08 > Crane Softwrights Ltd. http://www.CraneSoftwrights.com/s/ > Training tools: Comprehensive interactive XSLT/XPath 1.0/2.0 video > Video lesson: http://www.youtube.com/watch?v=PrNjJCh7Ppg&fmt=18 > Video overview: http://www.youtube.com/watch?v=VTiodiij6gE&fmt=18 > G. Ken Holman mailto:gkholman@xxxxxxxxxxxxxxxxxxxx > Male Cancer Awareness Nov'07 http://www.CraneSoftwrights.com/s/bc > Legal business disclaimers: http://www.CraneSoftwrights.com/legal
Current Thread |
---|
|
<- Previous | Index | Next -> |
---|---|---|
Re: [xsl] Move elements to precedin, G. Ken Holman | Thread | Re: [xsl] Move elements to precedin, G. Ken Holman |
Re: [xsl] Entity escaping/translati, dvint | Date | Re: [xsl] Move elements to precedin, G. Ken Holman |
Month |