xsl-list
[Top] [All Lists]

Re: [xsl] enclosing consecutive XHTML heading elements into <hgroup />, etc.

2013-09-12 12:26:54
Ivan,

This is much much easier in XSLT 2.0 using xsl:for-each-group. In this
case, I'd consider and test @group-starting-with="a | aa".

All by itself this capability is sufficient reason to use XSLT 2.0
whenever possible. I hope this option is available to you.

Cheers, Wendell


Wendell Piez | http://www.wendellpiez.com
XML | XSLT | electronic publishing
Eat Your Vegetables
_____oo_________o_o___ooooo____ooooooo_^


On Wed, Sep 11, 2013 at 5:18 AM, Ivan Shmakov <oneingray(_at_)gmail(_dot_)com> 
wrote:
        Long story short: the input XML has spans of elements which are
        to be enclosed within elements of some other kind, as in:

   <!-- Input -->
   <doc>
     <a /><a /><b /><b />
     <foo>
       <a /><b /><b />
       <aa /><a /><b />
     </foo>
   </doc>

   <!-- Output -->
   <doc>
     <enclosing>
       <a /><a /><b /><b />
       <foo>
         <enclosing><a /><b /><b /></enclosing>
         <enclosing><aa /><a /><b /></enclosing>
       </foo>
     </enclosing>
   </doc>

        Is there a simple way to do that, given that the set of the
        elements which can start such a span is finite (<a /> and <aa />
        in the example above), but they can otherwise occur anywhere?
        FWIW, I’m constrained to XSLT 1.0.

        The overall task is to introduce <article />, <section />,
        <header />, and <hgroup /> elements, as per the following
        example.

        Input:

<?xml version="1.0"?>
<html xmlns="http://www.w3.org/1999/xhtml";>
  <head><title>Hello, world!</title></head>
  <body>
    <h3>The well-known</h3>
    <h1>Hello, world!</h1>
    <h2>program</h2>

    <p>Here we discuss the generals…</p>

    <h2>J. R. Hacker’s implementation</h2>

    <p>And here are the particulars…</p>
  </body>
</html>

        Expected output:

<?xml version="1.0"?>
<html xmlns="http://www.w3.org/1999/xhtml";>
  <head><title>Hello, world!</title></head>
  <body>
    <article>
      <header>
        <hgroup>
          <h3>The well-known</h3>
          <h1>Hello, world!</h1>
          <h2>program</h2>
        </hgroup>
      </header>

      <p>Here we discuss the generals…</p>

      <section>
        <header>
          <h2>J. R. Hacker’s implementation</h2>
        </header>

        <p>And here are the particulars…</p>
      </section>
    </article>
  </body>
</html>

        Or, algorithmically speaking:

        • enclose the <body /> contents into an <article /> element, if
          there’s none;

        • enclose uninterrupted sequences of two or more heading (<h1 />
          to <h6 />) elements into <hgroup />s;

        • enclose the resulting <hgroup />s and the (so far unprocessed)
          singular heading elements into <header />s;

        • and finally, enclose all the <article /> elements starting
          with a <header /> element (including one) and stopping at the
          next <header /> (excluding one) into <section />s; the first
          <article />’s <header /> is to be excluded.

        My current implementation is at [1], and what makes me wonder is
        whether it’s possible to avoid a template like the following
        there:

  <xsl:template
      match="xhtml:h1[preceding-sibling::*[position () = 1][self::xhtml:h1 or 
self::xhtml:h2 or self::xhtml:h3 or self::xhtml:h4 or self::xhtml:h5 or 
self::xhtml:h6]] | xhtml:h2[preceding-sibling::*[position () = 
1][self::xhtml:h1 or self::xhtml:h2 or self::xhtml:h3 or self::xhtml:h4 or 
self::xhtml:h5 or self::xhtml:h6]] | xhtml:h3[preceding-sibling::*[position 
() = 1][self::xhtml:h1 or self::xhtml:h2 or self::xhtml:h3 or self::xhtml:h4 
or self::xhtml:h5 or self::xhtml:h6]] | 
xhtml:h4[preceding-sibling::*[position () = 1][self::xhtml:h1 or 
self::xhtml:h2 or self::xhtml:h3 or self::xhtml:h4 or self::xhtml:h5 or 
self::xhtml:h6]] | xhtml:h5[preceding-sibling::*[position () = 
1][self::xhtml:h1 or self::xhtml:h2 or self::xhtml:h3 or self::xhtml:h4 or 
self::xhtml:h5 or self::xhtml:h6]] | xhtml:h6[preceding-sibling::*[position 
() = 1][self::xhtml:h1 or self::xhtml:h2 or self::xhtml:h3 or self::xhtml:h4 
or self::xhtml:h5 or self::xhtml:h6]]"
      priority="2"
      >
    <!-- do nothing -->
  </xsl:template>

        TIA.

[1] http://am-1.org/~ivan/src/cxw3i61gtnuc78sbufiftcgz5f.xsl

--
FSF associate member #7257      http://sf-day.org/

--~------------------------------------------------------------------
XSL-List info and archive:  http://www.mulberrytech.com/xsl/xsl-list
To unsubscribe, go to: http://lists.mulberrytech.com/xsl-list/
or e-mail: 
<mailto:xsl-list-unsubscribe(_at_)lists(_dot_)mulberrytech(_dot_)com>
--~--


--~------------------------------------------------------------------
XSL-List info and archive:  http://www.mulberrytech.com/xsl/xsl-list
To unsubscribe, go to: http://lists.mulberrytech.com/xsl-list/
or e-mail: <mailto:xsl-list-unsubscribe(_at_)lists(_dot_)mulberrytech(_dot_)com>
--~--