[XSL-LIST Mailing List Archive Home] [By Thread] [By Date] [Recent Entries] [Reply To This Message]

Re: Move elements to preceding parent

Subject: Re: Move elements to preceding parent
From: Israel Viente <israel.viente@xxxxxxxxx>
Date: Wed, 17 Jun 2009 23:11:50 +0300
Re:  Move elements to preceding parent
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 "&#xa0;">]>
> <html xmlns="http://www.w3.org/1999/xhtml">
> <body>
>   <p dir="rtl">
>      <span class="chapter">line1</span>
>   </p>
>   <p dir="rtl">&nbsp;&nbsp;<br />
>   <span class="regular">line3.</span>
>   <span class="italic">line4</span>
>   <span class="regular">line5."</span>
>   </p>
>   <p dir="rtl">&nbsp;&nbsp;<br />
>   <span class="regular">line6.</span>
>   <br />
>   <span class="regular">line7</span>
>  </p>
>  <p dir="rtl">&nbsp;&nbsp;<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()],
>                                                     '[.?&#x22;]$')]">
>      <!--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()],'[.?&#x22;]$')]">
>          <!--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

PURCHASE STYLUS STUDIO ONLINE TODAY!

Purchasing Stylus Studio from our online shop is Easy, Secure and Value Priced!

Buy Stylus Studio Now

Download The World's Best XML IDE!

Accelerate XML development with our award-winning XML IDE - Download a free trial today!

Don't miss another message! Subscribe to this list today.
Email
First Name
Last Name
Company
Subscribe in XML format
RSS 2.0
Atom 0.3
Site Map | Privacy Policy | Terms of Use | Trademarks
Free Stylus Studio XML Training:
W3C Member
Stylus Studio® and DataDirect XQuery ™are products from DataDirect Technologies, is a registered trademark of Progress Software Corporation, in the U.S. and other countries. © 2004-2013 All Rights Reserved.