1

I was following this topic but still can not resolve bellow described issue. Inside <ol> elements I need to wrap arbitrary elements (/nodes) into <li> according this example:

<ol>
    text
    <p>text</p>
    <li>
        text
        <p>text</p>
    </li>
    <p>text</p>
    text
    <sub>text</sub>
</ol>

Convert to:

<ol>
    <li>
        text
        <p>text</p>
    </li>
    <li>
        text
        <p>text</p>
    </li>
    <li>
        <p>text</p>
        text
        <sub>text</sub>
    </li>
</ol>

I am using xslt 1.0. Highly appreciate any help!

UPDATED EXAMPLE

<root>
    <ol>
        text
        <p>text</p>
        <li>
           text
           <p>text</p>
        </li>
        <p>text</p>
        text
        <sub>text</sub>
    </ol>
    <ol>
        text
        <p>text</p>
    </ol>
</root>

Convert to:

<root>
    <ol>
        <li>
            text
            <p>text</p>
        </li>
        <li>
            text
            <p>text</p>
        </li>
        <li>
            <p>text</p>
            text
            <sub>text</sub>
        </li>
    </ol>
    <ol>
        <li>
            text
            <p>text</p>
        </li>
    </ol>
</root>
Community
  • 1
  • 1
PrincAm
  • 317
  • 5
  • 17

1 Answers1

2

I would try to solve it as Muenchian grouping, where the key counts the preceding-sibling::li elements of all non li child nodes of ol elements:

<?xml version="1.0" encoding="UTF-8" ?>
<xsl:transform xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">

    <xsl:key name="group" match="ol/node()[not(self::li)]" use="count(preceding-sibling::li)"/>

    <xsl:template match="@*|node()">
        <xsl:copy>
            <xsl:apply-templates select="@*|node()"/>
        </xsl:copy>
    </xsl:template>

    <xsl:template match="ol/node()[not(self::li)][generate-id() = generate-id(key('group', count(preceding-sibling::li))[1])]">
        <li>
            <xsl:copy-of select="key('group', count(preceding-sibling::li))"/>
        </li>
    </xsl:template>

    <xsl:template match="ol/node()[not(self::li)][not(generate-id() = generate-id(key('group', count(preceding-sibling::li))[1]))]"/>

</xsl:transform>

Online sample at http://xsltransform.net/pPzifpy.

Martin Honnen
  • 160,499
  • 6
  • 90
  • 110
  • Thanks! I've just realized that in the mentioned example I determined `
      ` as a root element. But it is not exactly my case. Therefore, I updated question. I will try to adapt your solution.
    – PrincAm Dec 10 '15 at 09:28