Re: Move elements to preceding parent
Dear Ken, I am sorry it looked as if I ignored your solution. I really tried to understand it but it had too many new things for me , and it looked hard to grasp the idea behind it. I should have write back, but I didn't know where to start from, while I got another solution that looked more close to my starting point. I now learnt the lesson and hope you get my sincere apology. I will read more about xsl:for-each-group, and your explanations on the code and learn how to use it for my needs. I must say I am very pleased that you wrote the stylesheet "defensively anticipating other conditions". You actually anticipated my needs even before I realised them thoroughly. Thanks again, Israel Viente On Wed, Jun 17, 2009 at 11:37 PM, G. Ken Holman<gkholman@xxxxxxxxxxxxxxxxxxxx> wrote: > At 2009-06-17 23:11 +0300, Israel Viente wrote: >> >> 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. > > As I tell my students, questions are not stupid if they are asked sincerely. > I far more appreciate the asking of questions than the ignoring of working > code that was supplied as requested. > >> 1. Why do we need the outer most copy element: >> > <xsl:template match="body"> >> > <xsl:copy> > > In order to preserve the body element when it comes time to group the > paragraphs. > >> How does it work in combination with xsl:for-each-group? > > By being the parent of the elements being grouped, matching on <body> gives > the stylesheet the opportunity to act on all of the children of body. The > paragraphs you want to massage are children of the body, so the time to act > on those children is at the time the body arrives at the stylesheet. Since > we want the body element to be part of the result, we preserve it with > <xsl:copy>. > >> 2. Can you please explain the group-ending-with selection? > > You can see by the select="*" that I have selected *all* of the children of > the body. I want to act on those groups of adjacent <p> elements. But > since there are other non-<p> elements that could be in the data (there > aren't any in your data, but how often is a web page made solely of > paragraphs?) I would be pulling those into the selection as well. After > all, I want all of the children of body to be processed in child order, I > only want to engage the special handling when I'm dealing with those > children that are paragraphs. > > Yes your data sample only contained paragraphs, but I try to write my > stylesheets defensively anticipating other conditions. > >> Why do we need *[not(self::p)] ? Doesn't it mean all except p elements? > > Indeed it does mean all except <p> elements. By putting non-<p> elements in > their own group, they won't interfere with the groups that are comprised of > <p> elements. > > So, adding more narrative to the stylesheet: > >> <xsl:template match="body"> >> <xsl:copy> >> <xsl:copy-of select="@*"/> > > The above preserves the body element and any attributes that might be > attached to it. > >> <xsl:for-each-group select="*" > > The above selects all of the children of the body. > >> group-ending-with="*[not(self::p)] | >> p[span/@class='chapter'] | >> p[matches(span[last()], >> '[.?"]$')]"> > > The above creates a group for every non-paragraph, a group for every > chapter, and a group for every consecutive sequence of paragraphs and ends > that group with a paragraph with the desired punctuation. > >> <!--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()],'[.?"]$')]"> > > The above tells me when I have encountered a group of <p> elements that ends > with a paragraph with the desired punctuation. > >> <!--in a group of p elements that end as required--> >> <xsl:copy> >> <xsl:copy-of select="@*"/> > > The above preserves the *first* of those paragraphs, and its attributes. > >> <!--preserve the content of the first of these p elements--> >> <xsl:apply-templates/> > > The above preserves the content of that paragraph. > >> <!--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)"/> > > The above preserves only the content of the other paragraphs in the group. > If there are no other paragraphs in the group, nothing else is added. If > there are 15 other paragraphs in the group, all of the content of all of > them are added. This is the generalized nature of the result: I'm not > assuming that there is only one other paragraph. > >> </xsl:copy> >> </xsl:when> >> <xsl:otherwise> >> <!--in another kind of group so just copy these using identity--> >> <xsl:apply-templates select="current-group()"/> > > The above preserves all of the children of <body> that are not paragraphs or > are chapter paragraphs. > >> </xsl:otherwise> >> </xsl:choose> >> </xsl:for-each-group> >> </xsl:copy> >> </xsl:template> > > I hope this has helped. Working directly with the sibling axes is fraught > with problems because of the reach of these axes usually past where we want > to stop looking. By looking *down* on the data, rather than left and right, > one can see a different perspective of your requirement. You expressed your > requirement by looking left and right from the given paragraph. I expressed > your requirement by looking down at the paragraphs from the <body> parent. > > Good luck in your work with XML and XSLT! As you learn more I'm sure you'll > love it more. > > . . . . . . . . . . . . Ken > > -- > 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
PURCHASE STYLUS STUDIO ONLINE TODAY!
Purchasing Stylus Studio from our online shop is Easy, Secure and Value Priced!
Download The World's Best XML IDE!
Accelerate XML development with our award-winning XML IDE - Download a free trial today!
Subscribe in XML format