[xsl] Wrapping nodes outside tables into paragraphs

Subject: [xsl] Wrapping nodes outside tables into paragraphs
From: "Martynas Jusevičius martynas@xxxxxxxxxxxx" <xsl-list-service@xxxxxxxxxxxxxxxxxxxxxx>
Date: Thu, 22 May 2014 19:18:55 -0000
Hey all,

I have TEI markup where nodes (text nodes and some elements) are
interspersed with table and figure elements, like this:

  <note>
    text text <ref type="whatever">text</ref>
    <table>...</table>
    text text
    <figure>...</figure>
    text text
    <table>...</table>
    <table>...</table>
    text text
  </note>

There can be nodes before, between, and after tables.

I want to produce a corresponding XHTML while also wrapping all the
nodes between tables into <p>, so they're on the same block-level (for
simplicity, lets say <xhtml:img> is also block-level):

  <xhtml:div>
    <xhtml:p>text text <a href="whatever">text</a></xhtml:p>
    <xhtml:table>...</xhtml:table>
    <xhtml:p>text text</xhtml:p>
    <xhtml:img/>
    <xhtml:p>text text</xhtml:p>
    <xhtml:table>...</xhtml:table>
    <xhtml:table>...</xhtml:table>
    <xhtml:p>text text</xhtml:p>
  </xhtml:div>

My approach for table only (code below) was to wrap all the nodes
before the matched table (if there are any; and after any previous
tables), and have a special case for the last table to grab the
following nodes as well.

It seemed to work, but after I discovered that <figure> also has to be
treated as <table>, the code is becoming less and less flexible. I was
wondering if there was a better way?

<xsl:template match="tei:table" mode="xhtml">
  ...
</xsl:template>

<xsl:template match="tei:note/node()[not(self::tei:table)]"
mode="xhtml" priority="1">
  <xsl:param name="wrap" select="false()" as="xs:boolean"/>

  <xsl:if test="$wrap">
    <xsl:next-match/>
  </xsl:if>
</xsl:template>

<xsl:template match="tei:note/tei:table[preceding-sibling::node()[not(self::tei:table)][following-sibling::tei:table[1]
is current()]]" mode="xhtml" priority="1">
  <xhtml:p>
    <xsl:apply-templates
select="preceding-sibling::node()[not(self::tei:table)][following-sibling::tei:table[1]
is current()]" mode="#current">
      <xsl:with-param name="wrap" select="true()"/>
    </xsl:apply-templates>
  </xhtml:p>

  <xsl:next-match/>

  <xsl:if test="following-sibling::node()[not(self::tei:table)][not(following-sibling::tei:table)][preceding-sibling::tei:table[1]
is current()]">
    <xhtml:p>
      <xsl:apply-templates
select="following-sibling::node()[not(self::tei:table)][not(following-sibling::tei:table)][preceding-sibling::tei:table[1]
is current()]" mode="#current">
        <xsl:with-param name="wrap" select="true()"/>
      </xsl:apply-templates>
    </xhtml:p>
  </xsl:if>
</xsl:template>

Thanks.

Martynas

Current Thread