Created
May 3, 2020 13:42
-
-
Save gimsieke/56311eee455bf43b2f685e9cfa699c37 to your computer and use it in GitHub Desktop.
XSLT problem raised by Michael Müller-Hillebrand on Mulberry’s xsl-list on 2020-05-03
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?xml version="1.0" encoding="UTF-8"?> | |
<div> | |
<h2 id="E2">Item with content to be joined follows div to collect</h2> | |
<div> | |
<ol data-meta="listlevel=start"> | |
<li> | |
<p>1st item</p> | |
</li> | |
</ol> | |
<div class="box" data-meta="collect"> | |
<p>Hint</p> | |
</div> | |
<ol data-meta="listlevel=continue"> | |
<li data-meta="listitem=continue"> | |
<p>Para ff</p> | |
</li> | |
<li> | |
<p>2nd item</p> | |
</li> | |
</ol> | |
<p>Other arbitrary content</p> | |
</div> | |
</div> |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?xml version="1.0" encoding="UTF-8"?> | |
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="3.0" | |
xmlns:my="http://localhost/" | |
xmlns:xs="http://www.w3.org/2001/XMLSchema" | |
exclude-result-prefixes="my xs"> | |
<xsl:mode on-no-match="shallow-copy"/> | |
<xsl:template match="*[ol[@data-meta = 'listlevel=start']]"> | |
<xsl:copy> | |
<xsl:apply-templates select="@*"/> | |
<!-- named template: then you can call it recursively for lower list levels | |
(not used here) --> | |
<xsl:call-template name="collect"> | |
<!-- We are grouping a) the list *items* in both special list types and | |
b) any other children of the current div. These a) and b) nodes are | |
returned by my:atomic-items() in document order: --> | |
<xsl:with-param name="nodes" select="my:atomic-items(.)"/> | |
</xsl:call-template> | |
</xsl:copy> | |
</xsl:template> | |
<xsl:function name="my:atomic-items" as="node()*"> | |
<xsl:param name="context" as="element()"/> | |
<xsl:variable name="special-lists" as="element(ol)*" | |
select="$context/(ol[@data-meta = ('listlevel=start', 'listlevel=continue')])" /> | |
<xsl:sequence | |
select="$context/* except $special-lists | $special-lists/li"/> | |
</xsl:function> | |
<xsl:template name="collect"> | |
<xsl:param name="nodes" as="node()*"/> | |
<!-- First grouping: Start with | |
ol[@data-meta = 'listlevel=start']/li[1] --> | |
<xsl:for-each-group select="$nodes" | |
group-starting-with="li[parent::ol[@data-meta = 'listlevel=start']] | |
[. is ../*[1]]"> | |
<xsl:choose> | |
<!-- The first group can, in principle, start with any other node | |
that precedes the actual first list starting item. Such an | |
uninteresting initial group will be processed in otherwise. --> | |
<xsl:when test="parent::ol[@data-meta = 'listlevel=start']"> | |
<!-- This is a grouping that may result in at most two groups: | |
The current list and anything non-collected and non-continuing | |
that might come after it (<p>Other arbitrary content</p>): --> | |
<xsl:for-each-group select="current-group()" | |
group-adjacent="exists(self::li) | |
or | |
@data-meta = 'collect'"> | |
<xsl:choose> | |
<xsl:when test="current-grouping-key()"> | |
<!-- We re-create the surrounding ol: --> | |
<ol> | |
<!-- The context element is the first li | |
in an ol[@data-meta = 'listlevel=start'] --> | |
<xsl:copy-of select="../@data-meta"/> | |
<xsl:for-each-group select="current-group()" | |
group-starting-with="li[not(@data-meta = | |
'listitem=continue')]"> | |
<!-- Create a new li: --> | |
<xsl:copy> | |
<xsl:copy-of select="@data-meta"/> | |
<xsl:apply-templates | |
select=" current-group()/self::li/node() | |
| current-group()[empty(self::li)]"/> | |
</xsl:copy> | |
</xsl:for-each-group> | |
</ol> | |
</xsl:when> | |
<xsl:otherwise> | |
<xsl:apply-templates select="current-group()"/> | |
</xsl:otherwise> | |
</xsl:choose> | |
</xsl:for-each-group> | |
</xsl:when> | |
<xsl:otherwise> | |
<xsl:apply-templates select="current-group()"/> | |
</xsl:otherwise> | |
</xsl:choose> | |
</xsl:for-each-group> | |
</xsl:template> | |
</xsl:stylesheet> |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?xml version="1.0" encoding="UTF-8"?> | |
<div> | |
<h2 id="E2">Item with content to be joined follows div to collect</h2> | |
<div> | |
<ol data-meta="listlevel=start"> | |
<li> | |
<p>1st item</p> | |
<div class="box" data-meta="collect"> | |
<p>Hint</p> | |
</div> | |
<p>Para ff</p> | |
</li> | |
<li> | |
<p>2nd item</p> | |
</li> | |
</ol> | |
<p>Other arbitrary content</p> | |
</div> | |
</div> |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment