xsl-list
[Top] [All Lists]

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

2013-09-11 04:19:35
        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>
--~--