简体   繁体   中英

numbering a table

The output should be html, use xsl to output the table of contents, following is the xml

<book title="D">
<author>
  <name>abc</name>
</author>

<chapter title="chapter1">
  <section title="section1.1"/>
  <section title="section1.2">
    <section title="section1.2.1"/>
<section title="section1.2.2"/>
  </section>
  <section title="section1.3">
<section title="section1.3.1"/>
  </section>
</chapter>

<chapter title="chapter2"/>

</book>

the result is html, as this:

<body>
  <h2>D</h2>
  <p>
     by abc
  </p>
  <h3>Table of contents</h3>
  <ul>
     <li>[1]chapter1
     <ul>
        <li>[1.1]section1.1</li>
        <li>[1.2]section1.2
        <ul>
           <li>[1.2.1]section1.2.1</li>
           <li>[1.2.2]section1.2.2</li>
        </ul>
        </li>
        <li>[1.3]section1.3
        <ul>
           <li>[1.3.1]section1.3.1</li>
        </ul>
        </li>
     </ul>
     </li>
     <li>[2]chapter2</li>
  </ul>
  </body>

UPDATE : The OP changed his provided XML after this solution was posted. The solution below produces the wanted, correct numbering. I am not updating it in order to catch-up with the OP's update, because I cannot spend all my time waiting when every next update will happen.

The power of using <xsl:number> is that no matter what update is done to the string values of the titles, the produced numbering continues to be correct. :)

This transformation :

<xsl:stylesheet version="1.0"  xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
 <xsl:output omit-xml-declaration="yes" indent="yes"/>
 <xsl:strip-space elements="*"/>

 <xsl:template match="node()|@*">
        <xsl:copy>
            <xsl:apply-templates select="node()|@*"/>
        </xsl:copy>
 </xsl:template>

 <xsl:template match="book">
        <body>
            <xsl:apply-templates select="node()|@*"/>
        </body>
 </xsl:template>

 <xsl:template match="book/@title">
        <h2>
            <xsl:value-of select="."/>
        </h2>
 </xsl:template>

 <xsl:template match="author">
        <p>by 
            <xsl:value-of select="name"/>
        </p>
        <h3>Table of Contents</h3>
        <ul>
            <xsl:apply-templates mode="TC"
                 select="following-sibling::*"/>
        </ul>
 </xsl:template>

 <xsl:template mode="TC"
      match="chapter[section]|section[section]">
        <li>
            [<xsl:number level="multiple"
             count="chapter|section"/>] <xsl:text/>
            <xsl:value-of select="@title"/>
            <ul>
                <xsl:apply-templates mode="TC"/>
            </ul>
        </li>
 </xsl:template>

 <xsl:template mode="TC" match=
    "chapter[not(section)]|section[not(section)]">
        <li>
            [<xsl:number level="multiple"
             count="chapter|section"/>] <xsl:text/>
            <xsl:value-of select="@title"/>
        </li>
 </xsl:template>

 <xsl:template match="chapter|section"/>
</xsl:stylesheet>

when applied on the provided XML document :

<book title="D">
    <author>
        <name>abc</name>
    </author>
    <chapter title="chapter1">
        <section title="section1.1"/>
        <section title="section1.2">
            <section title="section1.2.1"/>
            <section title="section1.2.2"/></section>
        <section title="section3">
            <section title="section3.1"/></section>
    </chapter>
    <chapter title="chapter2"/>
</book>

produces the wanted, correct result :

<body>
   <h2>D</h2>
   <p>by 
            abc</p>
   <h3>Table of Contents</h3>
   <ul>
      <li>
            [1] chapter1<ul>
            <li>
            [1.1] section1.1</li>
            <li>
            [1.2] section1.2<ul>
                  <li>
            [1.2.1] section1.2.1</li>
                  <li>
            [1.2.2] section1.2.2</li>
               </ul>
            </li>
            <li>
            [1.3] section3<ul>
                  <li>
            [1.3.1] section3.1</li>
               </ul>
            </li>
         </ul>
      </li>
      <li>
            [2] chapter2</li>
   </ul>
</body>

and it is displayed by the browser as :

D

by abc

Table of Contents

  • [1] chapter1
    • [1.1] section1.1
    • [1.2] section1.2
      • [1.2.1] section1.2.1
      • [1.2.2] section1.2.2
    • [1.3] section3
      • [1.3.1] section3.1
  • [2] chapter2

Explanation :

Use of <xsl:number> with level="multiple" counting both chapter and section .

This stylesheet:

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
    <xsl:template match="book">
        <body>
            <h2><xsl:apply-templates select="@title" /></h2>
            <p>by <xsl:apply-templates select="author/name" /></p>
            <h3>Table of contents</h3>
            <ul>
                <xsl:apply-templates select="chapter" />
            </ul>
        </body>
    </xsl:template>
    <xsl:template match="chapter|section">
        <li><xsl:call-template name="extract-num" /></li>
    </xsl:template>
    <xsl:template match="chapter[child::*]|section[child::*]">
        <li>
            <xsl:call-template name="extract-num" />
            <ul>
                <xsl:apply-templates />
            </ul>
        </li>
    </xsl:template>
    <xsl:template name="extract-num">
        <xsl:value-of select="concat('[', substring(@title, 8), ']', @title)" />
    </xsl:template>
</xsl:stylesheet>

On this input:

<book title="D">
    <author>
        <name>abc</name>
    </author>
    <chapter title="chapter1">
        <section title="section1.1" />
        <section title="section1.2">
            <section title="section1.2.1" />
            <section title="section1.2.2" />
        </section>
        <section title="section3">
            <section title="section3.1" />
        </section>
    </chapter>
    <chapter title="chapter2" />
</book>

Produces:

<body>
    <h2>D</h2>
    <p>by abc</p>
    <h3>Table of contents</h3>
    <ul>
        <li>[1]chapter1
            <ul>
                <li>[1.1]section1.1</li>
                <li>[1.2]section1.2
                    <ul>
                        <li>[1.2.1]section1.2.1</li>
                        <li>[1.2.2]section1.2.2</li>
                    </ul>
                </li>
                <li>[3]section3
                    <ul>
                        <li>[3.1]section3.1</li>
                    </ul>
                </li>
            </ul>
        </li>
        <li>[2]chapter2</li>
    </ul>
</body>

Note: Whitespace adjusted for formatting. If you actually need the exact whitespace you provide in your requested output, then you'll need to modify accordingly.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM