In the below example we are trying to handle Nested 'LIST' with 'label' of each 'list-item':
Label Example:
style="ListNum1" then a.,b.,c., ... etc.
style="ListNum2" then (1),(2),(3), ... etc.
style="ListNum3" then (a),(b),(c), ... etc.
Can anyone help.
INPUT XML:
<?xml version="1.0" encoding="UTF-8"?>
<body>
<list-item style="ListNum1"><p content-type="new">Your client may (<styled-content style="stat" style-type="Stat-Cal">Prob C §13659</styled-content>) because:</p></list-item>
<list-item style="ListNum2"><p content-type="new">For later income tax purposes</p></list-item>
<list-item style="ListNum3"><p content-type="new">Documents a “stepped-up basis” (<italic>i.e.,</italic> fair.</p></list-item>
<list-item style="ListNum3"><p content-type="new">Provides evidence for your client.</p></list-item>
<list-item style="ListNum2"><p content-type="new">If you or your <bold>client</bold>.</p></list-item>
<list-item style="ListNum1"><p content-type="new">If transfer <italic>unincorporated business</italic> appraisal. <styled-content style="stat" style-type="Stat-Cal">Prob C §13658</styled-content>.</p></list-item>
</body>
EXPECTED OUTPUT:
<?xml version="1.0" encoding="UTF-8"?>
<body>
<list type="ListNum1">
<list-item style="ListNum1"><label>a.</label><p content-type="new">Your client may (<styled-content style="stat" style-type="Stat-Cal">Prob C §13659</styled-content>) because:</p></list-item>
<list type="ListNum2">
<list-item style="ListNum2"><label>(1)</label><p content-type="new">For later income tax purposes</p>
<list type="ListNum3">
<list-item style="ListNum3"><label>(a)</label><p content-type="new">Documents a “stepped-up basis” (<italic>i.e.,</italic> fair.</p></list-item>
<list-item style="ListNum3"><label>(b)</label><p content-type="new">Provides evidence for your client.</p></list-item>
</list></list-item>
<list-item style="ListNum2"><label>(2)</label><p content-type="new">If you or your <bold>client</bold>.</p></list-item>
</list></list-item>
<list-item style="ListNum1"><label>b.</label><p content-type="new">If transfer <italic>unincorporated business</italic> appraisal. <styled-content style="stat" style-type="Stat-Cal">Prob C §13658</styled-content>.</p></list-item>
</list>
</body>
XSLT CODE:
<?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="node()|@*">
<xsl:copy>
<xsl:apply-templates select="node()|@*"/>
</xsl:copy>
</xsl:template>
<xsl:template match="list-item[@style='ListNum1']">
<xsl:if test="not(preceding-sibling::*[1][self::list-item[@style='ListNum1']])">
<xsl:text disable-output-escaping="yes"><![CDATA[<list list-type="ListNum1">]]></xsl:text>
</xsl:if>
<xsl:copy>
<xsl:copy-of select="@*"/>
<xsl:apply-templates/>
</xsl:copy>
<xsl:if test="not(following-sibling::*[1][self::list-item[@style='ListNum1']])">
<xsl:text disable-output-escaping="yes"><![CDATA[</list>]]></xsl:text>
</xsl:if>
</xsl:template>
<xsl:template match="list-item[@style='ListNum2']">
<xsl:if test="not(preceding-sibling::*[1][self::list-item[@style='ListNum2']])">
<xsl:text disable-output-escaping="yes"><![CDATA[<list list-type="ListNum2">]]></xsl:text>
</xsl:if>
<xsl:copy>
<xsl:copy-of select="@*"/>
<xsl:apply-templates/>
</xsl:copy>
<xsl:if test="not(following-sibling::*[1][self::list-item[@style='ListNum2']])">
<xsl:text disable-output-escaping="yes"><![CDATA[</list>]]></xsl:text>
</xsl:if>
</xsl:template>
<xsl:template match="list-item[@style='ListNum3']">
<xsl:if test="not(preceding-sibling::*[1][self::list-item[@style='ListNum3']])">
<xsl:text disable-output-escaping="yes"><![CDATA[<list list-type="ListNum3">]]></xsl:text>
</xsl:if>
<xsl:copy>
<xsl:copy-of select="@*"/>
<xsl:apply-templates/>
</xsl:copy>
<xsl:if test="not(following-sibling::*[1][self::list-item[@style='ListNum3']])">
<xsl:text disable-output-escaping="yes"><![CDATA[</list>]]></xsl:text>
</xsl:if>
</xsl:template>
</xsl:stylesheet>
Reference URL # https://xsltfiddle.liberty-development.net/93nwMoZ/1
The recursive grouping is like this:
<?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"
xmlns:mf="http://example.com/mf"
expand-text="yes"
exclude-result-prefixes="#all"
version="3.0">
<xsl:param name="format-map" as="map(xs:integer, xs:string)"
select="map { 1 : 'a', 2 : '1', 3 : 'A' }"/>
<xsl:function name="mf:group" as="node()*">
<xsl:param name="items" as="element(list-item)*"/>
<xsl:param name="level" as="xs:integer"/>
<xsl:where-populated>
<list type="ListNum{$level}">
<xsl:for-each-group select="$items" group-starting-with="list-item[@style = 'ListNum' || $level]">
<xsl:copy>
<label>{format-integer(position(), $format-map($level))}</label>
<xsl:apply-templates select="node(), mf:group(tail(current-group()), $level + 1)"/>
</xsl:copy>
</xsl:for-each-group>
</list>
</xsl:where-populated>
</xsl:function>
<xsl:mode on-no-match="shallow-copy"/>
<xsl:output method="xml" indent="yes"/>
<xsl:template match="body">
<xsl:copy>
<xsl:sequence select="mf:group(list-item, 1)"/>
</xsl:copy>
</xsl:template>
</xsl:stylesheet>
https://xsltfiddle.liberty-development.net/ei5R4v4
For the label formatting details, perhaps extend it as
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:xs="http://www.w3.org/2001/XMLSchema"
xmlns:mf="http://example.com/mf"
expand-text="yes"
exclude-result-prefixes="#all"
version="3.0">
<xsl:param name="format-map" as="map(xs:integer, xs:string)"
select="map { 1 : 'a', 2 : '1', 3 : 'a' }"/>
<xsl:function name="mf:format" as="xs:string">
<xsl:param name="number" as="xs:integer"/>
<xsl:param name="level" as="xs:integer"/>
<xsl:variable name="formatted-number"
select="format-integer($number, $format-map($level))"/>
<xsl:sequence
select="if ($level = 1)
then $formatted-number || '.'
else '(' || $formatted-number || ')'"/>
</xsl:function>
<xsl:function name="mf:group" as="node()*">
<xsl:param name="items" as="element(list-item)*"/>
<xsl:param name="level" as="xs:integer"/>
<xsl:where-populated>
<list type="ListNum{$level}">
<xsl:for-each-group select="$items" group-starting-with="list-item[@style = 'ListNum' || $level]">
<xsl:copy>
<label>{mf:format(position(), $level)}</label>
<xsl:apply-templates select="node(), mf:group(tail(current-group()), $level + 1)"/>
</xsl:copy>
</xsl:for-each-group>
</list>
</xsl:where-populated>
</xsl:function>
<xsl:mode on-no-match="shallow-copy"/>
<xsl:output method="xml" indent="yes"/>
<xsl:template match="body">
<xsl:copy>
<xsl:sequence select="mf:group(list-item, 1)"/>
</xsl:copy>
</xsl:template>
</xsl:stylesheet>