I have a xml like below:
<root>
<p>some text</p>
<ol>
<li>
<a href="some-link" rel="nofollow">link</a>
</li>
</ol>
<li>tag with parent as root</li>
<li>another li tag with parent as root</li>
<li>another li tag with parent as root</li>
<p>some more text</p>
<li>some text in li.</li>
<li>another li tag with parent as root</li>
<p>some more text</p>
<li>some text in li.</li>
<a href="http://cowherd.com" rel="nofollow">http://cowherd.com</a>
</root>
Desired output: I want to add a parent to the all li tags which don't have any parent and also I want to add the li tags into a common parent if there are more than one li tags coming in continuety.
<root>
<p>some text</p>
<ol>
<li>
<a href="some-link" rel="nofollow">link</a>
</li>
</ol>
<ul>
<li>tag with parent as root</li>
<li>another li tag with parent as root</li>
<li>another li tag with parent as root</li>
</ul>
<p>some more text</p>
<ul>
<li>some text in li.</li>
<li>another li tag with parent as root</li>
</ul>
<p>some more text</p>
<ul>
<li>some text in li.</li>
</ul>
</root>
I tried various things but doesn't work. Thanks in advance
<xsl:template match="li[not(parent::ol) and not(parent::ul)]">
<ul>
<xsl:copy-of select="."/>
</ul>
</xsl:template>
<xsl:template match="li[not(parent::ol) and not(parent::ul)]">
<xsl:for-each select="root/li">
<ul><xsl:value-of select="."/></ul>
</xsl:for-each>
</xsl:template>
<xsl:template match="li[not(parent::ol) and not(parent::ul)]">
<ul><xsl:apply-templates/></ul>
</xsl:template>
This is doable in XSLT 1 with a key, a rather convoluted one, but doing the job:
<xsl:stylesheet
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
version="1.0">
<xsl:output method="xml" indent="yes" />
<xsl:strip-space elements="*"/>
<xsl:key name="li-group" match="*[not(self::ol | self::ul)]/li[preceding-sibling::*[1][self::li]]" use="generate-id(preceding-sibling::li[not(preceding-sibling::*[1][self::li])][1])"/>
<xsl:template match="@* | node()">
<xsl:copy>
<xsl:apply-templates select="@* | node()"/>
</xsl:copy>
</xsl:template>
<xsl:template match="*[not(self::ol | self::ul)]/li[not(preceding-sibling::*[1][self::li])]">
<ul>
<xsl:copy-of select=". | key('li-group', generate-id())"/>
</ul>
</xsl:template>
<xsl:template match="*[not(self::ol | self::ul)]/li[preceding-sibling::*[1][self::li]]"/>
</xsl:stylesheet>
Other options are sibling recursion.