目录XSL

时间:2015-01-13 11:23:47

标签: html css xml xslt

问题:我正在做一个目录,包括章节,章节,小节和子小节。我想要的是用xsl处理信息(用XML格式),转换成HTML页面。

XML

<chapter id="c1">
        <title>Chapter 1</title>
        <section id="s1.1">
            <title>Motivation</title>
                 (...)

        <section id= "s1.2">
                 (...)
 <chapter id="c2">

        <title>Chapter 2 </title>
        <section id="s2.1">
             <title> Genetics </title>
                 <subsection id="ss2.1.1">
                      <title> Brief History </title> 
                     (...)

XSL

<xsl:template match="toc">
        <h3>Table of contents</h3>
        <ul> 
            <xsl:apply-templates mode="indice" select="//chapter">
            <xsl:sort/>
            </xsl:apply-templates>
        </ul>
</xsl:template>


<xsl:template mode="indice" match="chapter">      
    <h3> 
            <xsl:value-of select="title"/>
    </h3>

    <ol>
        <xsl:for-each select="section">               
            <li>
                <a href="#{@id}"> 
                    <xsl:value-of select="title"/>
                </a>  
                <ol>
                <xsl:for-each select="subsection">                      
                        <li>
                            <a href="#{@id}"> 
                                <xsl:value-of select="title"/>
                            </a>
                            <ol>
                                <xsl:for-each select="subsubsection">                      
                                    <li>
                                        <a href="#{@id}"> 
                                            <xsl:value-of select="title"/>
                                        </a>
                                    </li>
                                </xsl:for-each> 
                            </ol>
                        </li>                                               
                </xsl:for-each> 
                </ol>
            </li>               
        </xsl:for-each>
    </ol>
</xsl:template>

我使用以下CSS样式在有序列表中创建子列表:

<style>
     body{
        text-align: justify;
     }
     ol {counter-reset: item}
     li {display: block}
     li:before {content: counters(item, ".") ". "; counter-increment: item}
</style>

HTML中的当前结果:

 Chapter 1
       1. Motivation
       2. Objectives
       3. Thesis structure

 Chapter 2
       1. Genetics
          1.1. Brief History
          1.2. Topics
       2. Genes: study
          2.1. Eucariots
          2.2. Procaritots
       3. Stuff
          3.1. stuff
          3.2. stuff
                 3.2.1. stuff
                 3.2.2. stuff
          (...) 

HTML中的所需结果:

 Chapter 1
       1.1. Motivation
       1.2. Objectives
       1.3. Thesis structure

 Chapter 2
       2.1. Genetics
          2.1.1 Brief History
          2.1.2 Topics
       2.2. Genes: study
          2.2.1. Eucariots
          2.2.2. Procaritots
       2.3. Stuff
          2.3.1. stuff
          2.3.2. stuff
                 2.3.2.1. stuff
                 2.3.2.2. stuff
          (...) 

有什么建议吗?

2 个答案:

答案 0 :(得分:1)

计数是否必须在CSS中进行?如果没有,您可以使用<xsl:number>这样的内容:

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
    <xsl:template match="text()"/>
    <xsl:template match="text()" mode="indice"/>
    <xsl:template match="toc">
        <html>
            <body>
                <h3>Table of contents</h3>
                <ul>
                    <xsl:apply-templates mode="indice" select="//chapter">
                        <xsl:sort/>
                    </xsl:apply-templates>
                </ul>
            </body>
        </html>
    </xsl:template>
    <xsl:template match="chapter" mode="indice">
        <h3>
            <xsl:value-of select="title"/>
        </h3>
        <ul>
            <xsl:apply-templates mode="indice"/>
        </ul>
    </xsl:template>
    <xsl:template match="section" mode="indice">
        <li>
            <xsl:attribute name="data-value">
                <xsl:number count="chapter"/>
                <xsl:text>.</xsl:text>
                <xsl:number count="section"/>
                <xsl:text>.</xsl:text>
            </xsl:attribute>
            <a href="#{@id}">
                <xsl:value-of select="title"/>
            </a>
            <xsl:if test="subsection">
                <ul>
                    <xsl:apply-templates mode="indice"/>
                </ul>
            </xsl:if>
        </li>
    </xsl:template>
    <xsl:template match="subsection" mode="indice">
        <li>
            <xsl:attribute name="data-value">
                <xsl:number count="chapter"/>
                <xsl:text>.</xsl:text>
                <xsl:number count="section"/>
                <xsl:text>.</xsl:text>
                <xsl:number count="subsection"/>
                <xsl:text>.</xsl:text>
            </xsl:attribute>
            <a href="#{@id}">
                <xsl:value-of select="title"/>
            </a>
            <xsl:if test="subsubsection">
                <ul>
                    <xsl:apply-templates mode="indice"/>
                </ul>
            </xsl:if>
        </li>
    </xsl:template>
    <xsl:template match="subsubsection" mode="indice">
        <li>
            <xsl:attribute name="data-value">
                <xsl:number count="chapter"/>
                <xsl:text>.</xsl:text>
                <xsl:number count="section"/>
                <xsl:text>.</xsl:text>
                <xsl:number count="subsection"/>
                <xsl:text>.</xsl:text>
                <xsl:number count="subsubsection"/>
                <xsl:text>.</xsl:text>
            </xsl:attribute>
            <a href="#{@id}">
                <xsl:value-of select="title"/>
            </a>
        </li>
    </xsl:template>
</xsl:stylesheet>

(并且可能重构属性data-value的生成),然后像这样使用一些CSS:

li:before {
            content:attr(data-value);
        }

如果您的@id始终包含正确的数字,则可以将translate s替换为@id中的“{0}}并使用”无“,并显示使用CSS伪元素......

答案 1 :(得分:1)

如果您需要在CSS中进行编号,那么您可以执行此操作。 使用以下XSL:

<xsl:template match="toc">
      <h3>Table of contents</h3>
      <ul>
          <xsl:apply-templates mode="indice" select="//chapter"/>
      </ul>
</xsl:template>


<xsl:template mode="indice" match="chapter">
  <!-- Add a class on the list items related to a chapter -->
  <li class="chapter"> 
    <xsl:value-of select="title"/>
    <ol>
        <xsl:for-each select="section">               
            <li>
                <a href="#{@id}">
                  <xsl:value-of select="title"/>
                </a>
                <xsl:if test="subsection">
                  <ol>
                    <xsl:for-each select="subsection">
                      <li>
                          <a href="#{@id}"> 
                              <xsl:value-of select="title"/>
                          </a>
                          <xsl:if test="subsubsection">
                            <ol>
                              <xsl:for-each select="subsubsection">                      
                                <li>
                                  <a href="#{@id}"> 
                                      <xsl:value-of select="title"/>
                                   </a>
                                </li>
                              </xsl:for-each> 
                          </ol>
                        </xsl:if>
                      </li>                                               
                    </xsl:for-each> 
                  </ol>
                </xsl:if>
            </li>               
        </xsl:for-each>
    </ol>
  </li>
</xsl:template>

和以下CSS:

   body {
      text-align: justify;
   }
   ol, ul {
    counter-reset: item;
   }
   li {
    display: list-item;
    list-style-type: none;
   }
   li.chapter::before {
    content: "";
   }
   li:before {
    content: counters(item, ".") ". ";
    counter-increment: item
   }

结果就是你所期望的。