简体   繁体   中英

Issue with nested XSL apply-templates

I am trying to transform and xml file to html with xsl. At one point I need to populate a list of headings from particular tags (with the same nested structure).

Part of my xml file is below.

<description>
    <levelledPara>
        <title>Heading [1]</title>
        <para>Contains paragraph items</para>
        <levelledPara>
            <title>Heading [1.1]</title>
            <para>Lorem ipsum dolor sit amet, consectetuer adipiscing elit.</para>
        </levelledPara>
        <levelledPara>
            <title>Heading [1.2]</title>
            <para>Fusce aliquet pede non pede</para>
        </levelledPara>
        <levelledPara>
            <title>Heading [1.3]</title>
            <para>Suspendisse dui purus, scelerisque at, vulputate vitae, pretium mattis, nunc.</para></levelledPara>
        <levelledPara>
            <title>Heading [1.4]</title>
            <para>Aenean nec lorem. In porttitor. Donec laoreet nonummy augue.</para>
            <levelledPara>
                <title>Heading [1.4.1]</title>
                <para>Pellentesque porttitor, velit lacinia egestas auctor</para>
            </levelledPara>
                <levelledPara>
                <title>Heading [1.4.2]</title>
                <para>Pellentesque porttitor, velit lacinia egestas auctor</para>
            </levelledPara>
            <levelledPara>
                <title>Heading [1.4.3]</title>
                <para>Fusce aliquet pede non pede. Suspendisse dapibus lorem pellentesque magna. </para>
                <levelledPara>
                    <title>Heading [1.4.3.1]</title>
                    <para>Proin semper, ante vitae sollicitudin posuere, metus quam iaculis nibh.</para>
                    <levelledPara>
                        <title>Heading [1.4.3.1.1]</title>
                        <para>Ut tincidunt volutpat urna. Mauris eleifend nulla eget mauris.</para>
                    </levelledPara>
                    <levelledPara>
                        <title>Heading [1.4.3.1.2]</title>
                        <para>Ut tincidunt volutpat urna.</para>
                </levelledPara>
                </levelledPara>
                <levelledPara>
                    <title>Heading [1.4.3.2]</title>
                    <para>Proin semper, ante vitae sollicitudin posuere.</para>
                </levelledPara>
                <levelledPara>
                    <title>Heading [1.4.3.3]</title>
                    <para>Proin semper, ante vitae sollicitudin posuere.</para>
                </levelledPara>
                <levelledPara>
                    <title>Heading [1.4.3.4]</title>
                    <para>Proin semper, ante vitae sollicitudin posuere.</para>
                </levelledPara>
            </levelledPara>
            <levelledPara>
                <title>Heading [1.4.4]</title>
                <para>In hac habitasse platea dictumst.</para>
            </levelledPara>
            <levelledPara>
                <title>Heading [1.4.5]</title>
                <para>Quisque ornare placerat risus.</para>
            </levelledPara>
        </levelledPara>
        <levelledPara>
            <title>Heading [1.5]</title>
            <para> Sed aliquam odio vitae tortor. Proin hendrerit tempus arcu.</para>
        </levelledPara>
        <levelledPara>
            <title>Heading [1.6]</title>
            <para>Vivamus a mi. Morbi neque.</para>
        </levelledPara>
    </levelledPara>
    <levelledPara>
        <title>Heading [2]</title>
        <para>Proin semper, ante vitae sollicitudin posuere.</para>
    </levelledPara>
    <levelledPara>
        <title>Heading [3]</title>
        <para>Etiam at ligula et tellus ullamcorper ultrices.</para>
    </levelledPara>
</description>

XSL code:

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
    xmlns:xs="http://www.w3.org/2001/XMLSchema"
    exclude-result-prefixes="xs"
    version="2.0">
    <xsl:output method="html"></xsl:output>

    <xsl:template match="/">

         ...
            <body>
                ...

                <nav><ul><xsl:apply-templates select="//levelledPara" mode="toc"/></ul></nav>

                ...
            </body>

        ... 

<xsl:template match="levelledPara" mode="toc">
    <li>
    <xsl:value-of select="title"/>
    <xsl:if test="levelledPara">
        <ul>
        <xsl:apply-templates select="levelledPara" mode="toc"/>
        </ul>
        </xsl:if>
    </li>
</xsl:template>

Desired output:

  <nav>
     <ul>
        <li>Heading [1]
           <ul>
              <li>Heading [1.1]</li>
              <li>Heading [1.2]</li>
              <li>Heading [1.3]</li>
              <li>Heading [1.4]
                 <ul>
                    <li>Heading [1.4.1]</li>
                    <li>Heading [1.4.2]</li>
                    <li>Heading [1.4.3]
                       <ul>
                          <li>Heading [1.4.3.1]
                             <ul>
                                <li>Heading [1.4.3.1.1]</li>
                                <li>Heading [1.4.3.1.2]</li>
                             </ul>
                          </li>
                          <li>Heading [1.4.3.2]</li>
                          <li>Heading [1.4.3.3]</li>
                          <li>Heading [1.4.3.4]</li>
                       </ul>
                    </li>
                    <li>Heading [1.4.4]</li>
                    <li>Heading [1.4.5]</li>
                 </ul>
              </li>
              <li>Heading [1.5]</li>
              <li>Heading [1.6]</li>
           </ul>
        </li>
        <li>Heading [2]</li>
        <li>Heading [3]</li>
     </ul>
  </nav>

Actual output:

  <nav>
     <ul>
        <li>Heading [1]
           <ul>
              <li>Heading [1.1]</li>
              <li>Heading [1.2]</li>
              <li>Heading [1.3]</li>
              <li>Heading [1.4]
                 <ul>
                    <li>Heading [1.4.1]</li>
                    <li>Heading [1.4.2]</li>
                    <li>Heading [1.4.3]
                       <ul>
                          <li>Heading [1.4.3.1]
                             <ul>
                                <li>Heading [1.4.3.1.1]</li>
                                <li>Heading [1.4.3.1.2]</li>
                             </ul>
                          </li>
                          <li>Heading [1.4.3.2]</li>
                          <li>Heading [1.4.3.3]</li>
                          <li>Heading [1.4.3.4]</li>
                       </ul>
                    </li>
                    <li>Heading [1.4.4]</li>
                    <li>Heading [1.4.5]</li>
                 </ul>
              </li>
              <li>Heading [1.5]</li>
              <li>Heading [1.6]</li>
           </ul>
        </li>
        <li>Heading [1.1]</li>
        <li>Heading [1.2]</li>
        <li>Heading [1.3]</li>
        <li>Heading [1.4]
           <ul>
              <li>Heading [1.4.1]</li>
              <li>Heading [1.4.2]</li>
              <li>Heading [1.4.3]
                 <ul>
                    <li>Heading [1.4.3.1]
                       <ul>
                          <li>Heading [1.4.3.1.1]</li>
                          <li>Heading [1.4.3.1.2]</li>
                       </ul>
                    </li>
                    <li>Heading [1.4.3.2]</li>
                    <li>Heading [1.4.3.3]</li>
                    <li>Heading [1.4.3.4]</li>
                 </ul>
              </li>
              <li>Heading [1.4.4]</li>
              <li>Heading [1.4.5]</li>
           </ul>
        </li>
        <li>Heading [1.4.1]</li>
        <li>Heading [1.4.2]</li>
        <li>Heading [1.4.3]
           <ul>
              <li>Heading [1.4.3.1]
                 <ul>
                    <li>Heading [1.4.3.1.1]</li>
                    <li>Heading [1.4.3.1.2]</li>
                 </ul>
              </li>
              <li>Heading [1.4.3.2]</li>
              <li>Heading [1.4.3.3]</li>
              <li>Heading [1.4.3.4]</li>
           </ul>
        </li>
        <li>Heading [1.4.3.1]
           <ul>
              <li>Heading [1.4.3.1.1]</li>
              <li>Heading [1.4.3.1.2]</li>
           </ul>
        </li>
        <li>Heading [1.4.3.1.1]</li>
        <li>Heading [1.4.3.1.2]</li>
        <li>Heading [1.4.3.2]</li>
        <li>Heading [1.4.3.3]</li>
        <li>Heading [1.4.3.4]</li>
        <li>Heading [1.4.4]</li>
        <li>Heading [1.4.5]</li>
        <li>Heading [1.5]</li>
        <li>Heading [1.6]</li>
        <li>Heading [2]</li>
        <li>Heading [3]</li>
     </ul>
  </nav>

It seems that the template is applied over and over for the whole nested content. I can't figure out what may be the problem here.

It looks as if you should only select

            <nav><ul><xsl:apply-templates select="/description/levelledPara" mode="toc"/></ul></nav>

for the first processing step, then your other template takes care of the recursive processing of nested elements.

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