Nikku Kahel
Nikku Kahel

Reputation: 71

How to reset list numbering in xslt

I have an xml file:

<ul class="ul">
<li class="li">UL LI 1</li>
<li class="li">UL LI 2</li>
<li class="li">UL LI 3
    <ol class="ol">
        <li class="li">OL LI 1</li>
        <li class="li">OL LI 2
            <ul>
                <li class="li">UL LI 1</li>
                <li class="li">UL LI 2
                    <ol class="ol">
                        <li class="li">OL LI 1</li>
                        <li class="li">OL LI 2
                            <ol class="ol">
                                <li class="li">OL LI 1</li>
                                <li class="li">OL LI 2</li>
                                <li class="li">OL LI 3</li>
                            </ol>
                        </li>
                    </ol>
                </li>
            </ul>
        </li>
    </ol>
</li>

What i want to achieve is something like this:

If the parent of the ol is a ul, i want to reset the numbering, otherwise, the numbering must be inherited from it's parent. How can i do this in xslt?

I did try to solve this using this code:

                  <xsl:variable name="ol.parent" select="parent::*/parent::*/parent::*[contains(@class, ' ol ')]"/>

              <xsl:choose>
                <xsl:when test="not(empty($ol.parent))">
                  <xsl:number level="multiple" select="$ol.parent/ancestor-or-self::*[contains(@class, ' ol ')]" count="*[contains(@class, ' li ')]" format="1."/>
                </xsl:when>
                <xsl:otherwise>
                  <xsl:number level="multiple"  from="*[(contains(@class, ' ol ') or contains(@class, ' li '))]" format="1."/>
                </xsl:otherwise>
              </xsl:choose>

But it the ordered list doesn't inherit the multilevel number. It always starts with one.

Upvotes: 1

Views: 363

Answers (1)

Martin Honnen
Martin Honnen

Reputation: 167716

I think you can use <xsl:number format="1." level="multiple" from="ul/li/ol"/> in the context of match="ol/li" e.g. https://xsltfiddle.liberty-development.net/ncdD7kN:

<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
    xmlns:xs="http://www.w3.org/2001/XMLSchema"
    exclude-result-prefixes="#all"
    version="3.0">

  <xsl:mode on-no-match="shallow-copy"/>

  <xsl:output method="html" indent="yes" html-version="5"/>

  <xsl:template match="ol/li">
      <xsl:copy>
          <xsl:number format="1." level="multiple" from="ul/li/ol"/>
          <xsl:apply-templates/>
      </xsl:copy>
  </xsl:template> 

</xsl:stylesheet>

outputs

<ul class="ul">

   <li class="li">UL LI 1</li>

   <li class="li">UL LI 2</li>

   <li class="li">UL LI 3

      <ol class="ol">

         <li>1.OL LI 1</li>

         <li>2.OL LI 2

            <ul>

               <li class="li">UL LI 1</li>

               <li class="li">UL LI 2

                  <ol class="ol">

                     <li>1.OL LI 1</li>

                     <li>2.OL LI 2

                        <ol class="ol">

                           <li>2.1.OL LI 1</li>

                           <li>2.2.OL LI 2</li>

                           <li>2.3.OL LI 3</li>

                        </ol>

                     </li>

                  </ol>

               </li>

            </ul>

         </li>

      </ol>

   </li>

</ul>

Of course the xsl:number use remains the same if instead of the above simple and quick XSLT 3 test case with HTML output you instead use XSLT 2 and create XSL-FO instead of HTML: https://xsltfiddle.liberty-development.net/ncdD7kN/1.

Upvotes: 1

Related Questions