Reputation: 815
In my XML document I have encodings of milestones in a text, encoded with a self-closing element <milestone n="1"/>
. Thus, a text like so:
<p>
<seg><milestone n="1"/>Lorem ipsum dolor sit amet, consectetur adipiscing
elit, sed do eiusmod tempor incididunt <milestone n="2"/>ut labore
et dolore magna aliqua. Ut <quote>enim <note>ad</note></quote> minim <milestone n="3"/>veniam,
quis nostrud exercitation <milestone n="4"/>ullamco laboris nisi
ut aliquip ex ea commodo</seg>
<seg>consequat. Duis aute irure dolor
<milestone n="5"/> in reprehenderit <quote>in</quote> voluptate velit esse cillum
dolore eu fugiat nulla pariatur.</seg>
</p>
With XSLT 2.0 I am trying to target an HTML output, where all content between each <milestone/>
is put into an li
HTML element, ignoring the <seg>
structure, but allowing for further processing over other nodes:
<li>Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt</li>
<li>ut labore et dolore magna aliqua. Ut enim ad minim</li>
<li>veniam, quis nostrud exercitation</li>
<li>ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor</li>
<li>in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur.</li>
The example (below based on this and this) did not function...
<xsl:template match="p" mode="diplo">
<xsl:for-each-group select="node()" group-starting-with="milestone">
<li>
<xsl:sequence select="current()/ancestor::p//milestone/@*"/>
<xsl:apply-templates select="current-group()[not(self::milestone)]"/>
</li>
</xsl:for-each-group>
</xsl:template>
EDIT: I've updated the XML source to be more clear (I don't want just text, but all nodes for further processing with apply templates), and posted a failed attempt.
Thanks in advance.
Upvotes: 0
Views: 79
Reputation: 1816
You need to use for-each-group
and @group-starting-with
like below:
XSLT 2.0:
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:xs="http://www.w3.org/2001/XMLSchema"
exclude-result-prefixes="xs"
version="2.0">
<xsl:output indent="yes"/>
<xsl:template match="p">
<p>
<xsl:for-each-group select="seg/node()" group-starting-with="milestone">
<xsl:sort select="@n"/>
<li>
<!--<xsl:value-of select="normalize-space(string-join(current-group(),' '))"/>-->
<xsl:apply-templates select="current-group()[not(self::milestone)]"/>
</li>
</xsl:for-each-group>
</p>
</xsl:template>
<xsl:template match="quote">
<xsl:text>"</xsl:text><xsl:apply-templates/><xsl:text>"</xsl:text> <!--output contents of <quote> in " " -->
</xsl:template>
<xsl:template match="note">
<xsl:text>[</xsl:text><xsl:apply-templates/><xsl:text>]</xsl:text> <!--output contents of <note> in [ ] -->
</xsl:template>
</xsl:stylesheet>
INPUT:
<?xml version="1.0" encoding="UTF-8"?>
<p>
<seg><milestone n="1"/>Lorem ipsum dolor sit amet, consectetur adipiscing
elit, sed do eiusmod tempor incididunt <milestone n="2"/>ut labore
et dolore magna aliqua. Ut <quote>enim <note>ad</note></quote> minim <milestone n="3"/>veniam,
quis nostrud exercitation <milestone n="4"/>ullamco laboris nisi
ut aliquip ex ea commodo</seg>
<seg>consequat. Duis aute irure dolor
<milestone n="5"/> in reprehenderit <quote>in</quote> voluptate velit esse cillum
dolore eu fugiat nulla pariatur.</seg>
</p>
OUTPUT:
<?xml version="1.0" encoding="UTF-8"?>
<p>
<li>Lorem ipsum dolor sit amet, consectetur adipiscing
elit, sed do eiusmod tempor incididunt </li>
<li>ut labore
et dolore magna aliqua. Ut "enim [ad]" minim </li>
<li>veniam,
quis nostrud exercitation </li>
<li>ullamco laboris nisi
ut aliquip ex ea commodoconsequat. Duis aute irure dolor
</li>
<li> in reprehenderit "in" voluptate velit esse cillum
dolore eu fugiat nulla pariatur.</li>
</p>
Upvotes: 1