Thanks a lot Graydon! And sorry, yes I'm using XSLT 2.0.
I suspected xsl:for-each-group can be used to solved this. I just
never seem to get the group- criteria right, or maybe I didn't realize
the grouping key could be used so flexibly.
My template now looks like this and seems to work:
<xsl:template match="tei:note[tei:table or tei:figure]" mode="xhtml">
<xsl:for-each-group select="node()" group-adjacent="if
(self::tei:table or self::tei:figure) then 'block' else 'inline'">
<xsl:choose>
<xsl:when test="current-grouping-key() eq 'block'">
<xsl:apply-templates select="current-group()" mode="#current"/>
</xsl:when>
<xsl:when test="current-grouping-key() eq 'inline'">
<xhtml:p>
<xsl:apply-templates select="current-group()" mode="#current"/>
</xhtml:p>
</xsl:when>
<xsl:otherwise>
<xsl:message terminate="yes">Grouping error</xsl:message>
</xsl:otherwise>
</xsl:choose>
</xsl:for-each-group>
</xsl:template>
Martynas
On Thu, May 22, 2014 at 9:55 PM, Graydon graydon(_at_)marost(_dot_)ca
<xsl-list-service(_at_)lists(_dot_)mulberrytech(_dot_)com> wrote:
On Thu, May 22, 2014 at 07:19:02PM -0000, Martynas Jusevičius
martynas(_at_)graphity(_dot_)org scripsit:
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):
This is a classic use case for XSLT 2.0's for-each-group instruction.
Are you using 2.0?
If so, an approach like
<xsl:for-each-group select="note/node()" group-adjacent="if
(self::table) then 'table' else 'interstitial'">
<xsl:choose>
<xsl:when test="current-grouping-key() eq 'table'">
<!-- do what you do to tables -->
</xsl:when>
<xsl:when test="current-grouping-key() eq 'interstial'>
<!-- wrap everything else -->
<xsl:otherwise>
<!-- you should never get here; die loudly -->
</xsl:otherwise>
</xsl:choose>
</xsl:for-each-group>
ought to work. (The pattern also extends.)
If you have to individual wrap adjacent tables you may want a different
grouping attribute, and you might want to select
note/node()[normalize-space()] instead, to avoid white-space only text
nodes.
-- Graydon
--~----------------------------------------------------------------
XSL-List info and archive: http://www.mulberrytech.com/xsl/xsl-list
EasyUnsubscribe: http://lists.mulberrytech.com/unsub/xsl-list/1167547
or by email: xsl-list-unsub(_at_)lists(_dot_)mulberrytech(_dot_)com
--~--