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

Re: select immediately following siblings with constr

Subject: Re: select immediately following siblings with constraints?
From: "James A. Robinson" <jim.robinson@xxxxxxxxxxxx>
Date: Fri, 24 Feb 2006 02:20:11 -0800
xsl immediately following sibling
> At 01:54 PM 2/23/2006, you wrote:
> >Thank you very much for the reply.  I actually hadn't been aware of
> >the << and >> operators, I shall have to read up on them.
> 
> Yes, they're fun, and ought to be useful for all kinds of neat things 
> we haven't discovered yet.

Yes indeed!  So I ended up using <<, it seems to be exactly what I
wanted.  It is still processing elements unnecessarily because my
expression has it testing all following-siblings, but hopefully the
testing of position in document order is less intensive then doing all
that unnecessary grouping.

I decided to make it more readable (to me, at least) by splitting the
creation of a $stop node from the processing of the following-sibling
sections.

Here's the complete solution for my merging problem:

  <!--
    Recursively merge adjoining sections into a single section.
    
    We test $sections to see if there is any instance of a
    section whose first preceding-sibling element is a section
    with an identical id.
    
    If the test is true, we recursively call ourselves, passing
    in the document returned by the merged_toc template, which
    merges adjacent sections sharing a section id.
  -->
  <xsl:template name="merge_sections">
    <xsl:param name="sections" as="document-node()" />
    <xsl:choose>
      <xsl:when test="exists($sections//section[@id = preceding-sibling::element()[1][self::section]/@id])">
        <xsl:call-template name="merge_sections">
          <xsl:with-param name="sections">
            <xsl:apply-templates select="$sections" mode="merged_toc" />
          </xsl:with-param>
        </xsl:call-template>
      </xsl:when>
      <xsl:otherwise>
        <xsl:sequence select="$sections" />
      </xsl:otherwise>
    </xsl:choose>
  </xsl:template>

  <!--
    Merge adjoining sections sharing a section id into a single group,
    skipping sections we infer were previously handled.
  -->
  <xsl:template match="section" mode="merged_toc" as="element(section)?">
    <!--
      If the immediately preceding element is a section which has the
      same id, it should have already been handled. Otherwise we want
      to copy it.
    -->
    <xsl:if test="not(preceding-sibling::element()[1][self::section][@id = current()/@id])">
      <xsl:copy>
        <xsl:sequence select="@*" />
        <xsl:apply-templates select="*" mode="#current" />

        <!--
          Now we want to pull in the children of any consecutive sequence
          of immediately following sibling sections which have the same id
          as the current section.

          We first test to see if the immediately following element is
          a section with the same id as the current section. If this
          isn't the case, we know we aren't supposed to do any merges.

          If we pass the test, we construct $stop, setting it to the
          first following-sibling::element() which is not a section
          with an identical section id to our own.

          If $stop has a value, we apply templates to following-sibling
          sections which are positioned, in document order, before $stop.
          If $stop does not have a value, all the following-sibling
          sections share our section id, and we can merge them all.
        -->
        <xsl:if test="following-sibling::element()[1][self::section][@id = current()/@id]">
          <xsl:variable name="stop"
            select="following-sibling::element()[
                      self::article or self::section[@id != current()/@id]][1]" />
          <xsl:choose>
            <xsl:when test="$stop">
              <xsl:apply-templates select="following-sibling::section[. &lt;&lt; $stop]/*" mode="#current" />
            </xsl:when>
            <xsl:otherwise>
              <xsl:apply-templates select="following-sibling::section/*" mode="#current" />
            </xsl:otherwise>
          </xsl:choose>
        </xsl:if>
    </xsl:copy>
    </xsl:if>
  </xsl:template>

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
James A. Robinson                       jim.robinson@xxxxxxxxxxxx
Stanford University HighWire Press      http://highwire.stanford.edu/
+1 650 7237294 (Work)                   +1 650 7259335 (Fax)

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.