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

Subject: [xsl] enclosing consecutive XHTML heading elements into <hgroup />, etc.
From: Ivan Shmakov <oneingray@xxxxxxxxx>
Date: Wed, 11 Sep 2013 09:18:34 +0000
	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, Ibm 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 generalsb&</p>

    <h2>J. R. Hackerbs implementation</h2>

    <p>And here are the particularsb&</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 generalsb&</p>

      <section>
	<header>
	  <h2>J. R. Hackerbs implementation</h2>
	</header>

	<p>And here are the particularsb&</p>
      </section>
    </article>
  </body>
</html>

	Or, algorithmically speaking:

	b" enclose the <body /> contents into an <article /> element, if
	  therebs none;

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

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

	b" 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 />bs <header /> is to be excluded.

	My current implementation is at [1], and what makes me wonder is
	whether itbs 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/

Current Thread