Reputation: 65
I have a nested list, and therefore I want the label to be nested too.
This is my code:
<!-- For first list -->
<xsl:template name="list1-label">
<xsl:number format="1."/>
</xsl:template>
<!-- The nestled list -->
<xsl:template name="list2-label">
<xsl:number format="1.1."/>
</xsl:template>
The first number in the last template (1.1.) I want to be relative to the parent item, in this case; "3".
Here is the xml structure:
<list1>
<item>Test</item>
<item>Test</item>
<list2>
<item>Test</item>
<item>Test</item>
</list2>
<item>Test</item>
</list1>
Here is the output:
1. Test
2. Test
2.1. Test
2.2. Test
3. Test
Upvotes: 2
Views: 827
Reputation: 24826
The wanted output can be obtained (for example) applying the advanced attributes @from and @count of xsl:number
. Here a working example from which you should get started:
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output indent="yes"/>
<xsl:strip-space elements="*"/>
<xsl:template match="list1/item">
<xsl:number level="any" from="list1" count="list1/item"/>
<xsl:text>. </xsl:text>
<xsl:value-of select="."/>
<xsl:text> </xsl:text>
</xsl:template>
<xsl:template match="list1/list2/item">
<xsl:text>	</xsl:text>
<xsl:number level="any" from="list1" count="list1/item"/>
<xsl:text>.</xsl:text>
<xsl:number level="any" from="list2" count="list2/item"/>
<xsl:text>. </xsl:text>
<xsl:value-of select="."/>
<xsl:text> </xsl:text>
</xsl:template>
</xsl:stylesheet>
If you want to simplify the match patterns:
<xsl:template match="list1">
<xsl:apply-templates />
</xsl:template>
<xsl:template match="list1/item">
<xsl:number level="any" from="list1" count="list1/item"/>
<xsl:text>. </xsl:text>
<xsl:value-of select="."/>
<xsl:text> </xsl:text>
</xsl:template>
<xsl:template match="list2/item">
<xsl:text>	</xsl:text>
<xsl:number level="any" from="list1" count="list1/item"/>
<xsl:text>.</xsl:text>
<xsl:number level="any" from="list2" count="list2/item"/>
<xsl:text>. </xsl:text>
<xsl:value-of select="."/>
<xsl:text> </xsl:text>
</xsl:template>
This latest example will correctly drive you to further nesting levels as with a list3.
Upvotes: 1
Reputation: 24826
This new transform is generalized to handle a variable number of lists.
Input sample:
<list1>
<item>Test</item>
<item>Test</item>
<list2>
<item>Test</item>
<list3>
<item>Test</item>
<item>Test</item>
</list3>
<item>Test</item>
<list3>
<item>Test</item>
</list3>
<item>Test</item>
</list2>
<item>Test</item>
</list1>
transform:
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output indent="yes" omit-xml-declaration="yes"/>
<xsl:strip-space elements="*"/>
<xsl:template match="*[starts-with(name(),'list')]">
<xsl:apply-templates>
<xsl:with-param name="tab" select="true()"/>
</xsl:apply-templates>
</xsl:template>
<xsl:template match="item">
<xsl:param name="lvl" select="count(ancestor::*)"/>
<xsl:param name="tab" select="false()"/>
<!-- insert entry point tab -->
<xsl:apply-templates select="text()[$tab and $lvl > 1]" mode="tab">
<xsl:with-param name="lvl" select="$lvl - 1"/>
</xsl:apply-templates>
<!-- recurse levels -->
<xsl:variable name="name" select="name(ancestor::*[$lvl])"/>
<xsl:number level="any" from="*[name()=$name]"
count="*[name()=$name]/item"/>
<xsl:text>.</xsl:text>
<xsl:apply-templates select="self::item[$lvl > 1]">
<xsl:with-param name="lvl" select="$lvl - 1"/>
</xsl:apply-templates>
<!-- print value -->
<xsl:if test="$lvl = 1">
<xsl:text> </xsl:text>
<xsl:value-of select="."/>
<xsl:text> </xsl:text>
</xsl:if>
</xsl:template>
<xsl:template match="text()" mode="tab">
<xsl:param name="lvl"/>
<xsl:text>	</xsl:text>
<xsl:apply-templates select="self::text()[$lvl>1]" mode="tab">
<xsl:with-param name="lvl" select="$lvl - 1"/>
</xsl:apply-templates>
</xsl:template>
</xsl:stylesheet>
output:
1. Test
2. Test
2.1. Test
2.1.1. Test
2.1.2. Test
2.2. Test
2.2.1. Test
2.3. Test
3. Test
Upvotes: 1
Reputation: 163549
For the nested list you should probably be using level="multiple" count="X|Y"
but I can't be more precise than that without knowing (a) what your XML source looks like, and (b) what the context item is at the point where your named templates are called.
Upvotes: 1