If following-sibling li
element of p
then how to move li
element?
Input
<root>
<p>start</p>
<p>aaaaa</p>
<li>aaa</li>
<li>bbb</li>
<li>ccc</li>
<p>aaaaa</p>
<p>aaaaaa</p>
**Expected Output**
<root>
<p>start</p>
<p>aaaaa
<li>aaa</li>
<li>bbb</li>
<li>ccc</li>
</p>
<p>aaaaa</p>
<p>aaaaaa</p>
XSLT:
<xsl:template match="@*|node()">
<xsl:copy>
<xsl:apply-templates select="@*|node()"/>
</xsl:copy>
</xsl:template>
<xsl:template match="p">
<p>
<xsl:apply-templates/>
<xsl:if test="following-sibling::*[1][self::li]">
<xsl:for-each select="following-sibling::*[1][self::li]">
<li><xsl:value-of select="."/></li>
</xsl:for-each>
</xsl:if>
</p>
</xsl:template>
Because you can use XSLT-2.0, you can make use of xsl:for-each-group
. So the following is one way to achieve the desired result:
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="2.0">
<xsl:strip-space elements="*" />
<xsl:output indent="yes" />
<xsl:template match="@* | node()">
<xsl:copy>
<xsl:apply-templates select="@* | node()" />
</xsl:copy>
</xsl:template>
<xsl:template match="p[name(following-sibling::*[1]) = 'li']">
<xsl:copy>
<xsl:apply-templates select="@* | node()" />
<xsl:for-each-group select="following-sibling::*" group-adjacent="name()">
<xsl:if test="position()=1">
<xsl:copy-of select="current-group()" />
</xsl:if>
</xsl:for-each-group>
</xsl:copy>
</xsl:template>
<xsl:template match="li[preceding-sibling::*[1] = (preceding-sibling::p[1] | preceding-sibling::li[1])]" />
</xsl:stylesheet>
The output is:
<?xml version="1.0" encoding="UTF-8"?>
<root>
<p>start</p>
<p>aaaaa<li>aaa</li>
<li>bbb</li>
<li>ccc</li>
</p>
<p>aaaaa</p>
<p>aaaaaa</p>
</root>