Re: [xsl] processing following-siblings to a point

Subject: Re: [xsl] processing following-siblings to a point
From: "G. Ken Holman" <gkholman@xxxxxxxxxxxxxxxxxxxx>
Date: Thu, 09 Jul 2009 15:11:18 -0400
At 2009-07-09 18:59 +0000, charlieo0@xxxxxxxxxxx wrote:
I've run into a structure that I must transform that I just haven't found a solution for. XSL 1.0 only. (I just don't have the proficiency for 2.0 yet).

Then this is your chance to learn! :{)}


I'm transforming what was a rather flat SGML structure to an XML structure. Here's the input structure:
...
Resulting structure tree:
...


My template (or at least the important part).

<xsl:template match="gen/title" mode="move">

<para0>
<title>
<xsl:value-of select="."/>
</title>
<subpara1>
<title><xsl:value-of select="following-sibling::subtitle[1]"/></title>
<xsl:apply-templates select="following-sibling::para"/>
</subpara1>
</para0>


My problem is with the <xsl:apply-templates select="following-sibling::para"/> line. Of course, all of the para elements are following siblings of all the gen/title elements. How can I express the <apply-templates> to process only the para element siblings BEFORE the next following title sibling. (This is difficult because EVERYTHING is a sibling of everything else).

Precisely! And for this reason, attacking the problem with XSLT 1.0 is a royal pain. You probably need a template to match sibling elements, then process one sibling at a time. Not pretty.


I will let another volunteer undertake to show you the answer using XSLT 1 ... below is an answer using XSLT 2.

I hope this helps (if not now, then in the future when you finally embrace XSLT 2).

. . . . . . . . . . Ken


T:\ftemp>type charlie.xml <gen> <title>TITLE_1</title> <subtitle>SUBTITLE_1</subtitle> <para>Text.</para> <para>Text.</para> <para>Text.</para> <title>TITLE_2</title> <subtitle>SUBTITLE_2</subtitle> <para>Text.</para> <para>Text.</para> <para>Text.</para> <para>Text.</para> <title>TITLE_3</title> <subtitle>SUBTITLE_3</subtitle> <para>Text.</para> <para>Text.</para> <para>Text.</para> <para>Text.</para> </gen>

T:\ftemp>call xslt2 charlie.xml charlie.xsl
<?xml version="1.0" encoding="UTF-8"?>
<para0>
   <title>TITLE_1</title>
   <subpara1>
      <title>SUBTITLE_1</title>
      <para>Text.</para>
      <para>Text.</para>
      <para>Text.</para>
   </subpara1>
</para0>
<para0>
   <title>TITLE_2</title>
   <subpara1>
      <title>SUBTITLE_2</title>
      <para>Text.</para>
      <para>Text.</para>
      <para>Text.</para>
      <para>Text.</para>
   </subpara1>
</para0>
<para0>
   <title>TITLE_3</title>
   <subpara1>
      <title>SUBTITLE_3</title>
      <para>Text.</para>
      <para>Text.</para>
      <para>Text.</para>
      <para>Text.</para>
   </subpara1>
</para0>
T:\ftemp>type charlie.xsl
<?xml version="1.0" encoding="US-ASCII"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform";
                version="2.0">

<xsl:output indent="yes"/>

<xsl:template match="gen">
  <xsl:for-each-group select="*" group-starting-with="title">
    <para0>
      <xsl:copy-of select="."/>
      <subpara1>
        <xsl:for-each select="current-group()[self::subtitle]">
          <title>
            <xsl:copy-of select="node()"/>
          </title>
        </xsl:for-each>
        <xsl:copy-of
            select="current-group()[not(self::title|self::subtitle)]"/>
      </subpara1>
    </para0>
  </xsl:for-each-group>
</xsl:template>

</xsl:stylesheet>

T:\ftemp>rem Done!



--
Possible July/August XSLT/XQuery/XSL-FO training in Oakland/CA/USA
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