i would like to convert xhtml to dokuwiki syntax using xslt.
now, one thing i can not seem to work my head around is how to handle nested lists. the dokuwiki syntax uses an asterisk (*) for a list item which is prepended by two white spaces per nesting level (c.f. wiki syntax).
my question: in the following example, how can the <xsl:template mach="li"> that matches the list item 2.1.1 be aware of it's nesting level, in order to prepend the right amount of white spaces?
* list item 1
* list item 2
* list item 2.1
* list item 2.1.1
* list item 2.2
* list item 2.3
* list item 3
corresponds to
which is how the following html is displayed:
<ul>
<li>
list item 1
</li>
<li>
list item 2
<ul>
<li>
list item 2.1
<ul>
<li>list item 2.1.1</li>
</ul>
</li>
<li>list item 2.2</li>
<li>list item 2.3</li>
</ul>
</li>
<li>
list item 3
</li>
</ul>
The following transformation:
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="text"/>
<xsl:strip-space elements="*"/>
<xsl:variable name="vBlanks"
select="' '"/>
<xsl:variable name="vnNestSpaces" select="2"/>
<xsl:template match="li">
<xsl:variable name="vNestLevel"
select="count(ancestor::li)"/>
<xsl:value-of select=
"concat('
',
substring($vBlanks,1,$vnNestSpaces*$vNestLevel),
'* ', normalize-space(text()[1])
)"/>
<xsl:apply-templates select="*"/>
</xsl:template>
</xsl:stylesheet>
when applied on the original XML document:
<ul>
<li> list item 1
</li>
<li> list item 2
<ul>
<li> list item 2.1
<ul>
<li>list item 2.1.1</li>
</ul>
</li>
<li>list item 2.2</li>
<li>list item 2.3</li>
</ul>
</li>
<li> list item 3 </li>
</ul>
produces the desired result:
* list item 1
* list item 2
* list item 2.1
* list item 2.1.1
* list item 2.2
* list item 2.3
* list item 3
Do note the following:
The required indentation is determined by the value of count(ancesstor::li).
The space for indenting is taken directly from a sufficiently large blank line (contains enough blanks for 20 levels of nesting). There is no need to recursively output the spaces one by one.
The transformation is more efficient, due to 2. above.
Note the use of the XPath substring() function.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With