jbrehr
jbrehr

Reputation: 815

XSLT 2.0 outputting html list based on content between self-closing elements

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

Answers (1)

Amrendra Kumar
Amrendra Kumar

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

Related Questions