How to generate html TOC identifier in XSLT?
-
02-07-2021 - |
Frage
I would like to generate table of content identifiers in an HTML document generated with XSL.
From the following format:
<?xml version="1.0" encoding="utf-8"?>
<section>
<header>Heading 1</header>
<section>
<section>
<section>
<header>Heading 4</header>
</section>
</section>
</section>
<section>
<header>Heading 2</header>
<section>
<section>
<section>
<header>Heading 5</header>
</section>
</section>
</section>
<section>
<header>Heading 3</header>
</section>
</section>
<section>
<header>Heading 2</header>
</section>
</section>
I am already able to generate:
<?xml version="1.0" encoding="utf-8"?>
<h1>Heading 1</h1>
<h4>Heading 4</h4>
<h2>Heading 2</h2>
<h5>Heading 5</h5>
<h6>Heading 6</h6>
<h2>Heading 2</h2>
Thanks to:
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="html" indent="yes" encoding="UTF-8" />
<xsl:template match="/">
<xsl:apply-templates/>
</xsl:template>
<xsl:template match="header">
<xsl:variable name="level" select="count(ancestor-or-self::section)"/>
<xsl:element name="h{$level}">
<xsl:apply-templates/>
</xsl:element>
</xsl:template>
But I need to add an additional TOC identifier to have:
<?xml version="1.0" encoding="utf-8"?>
<a name="toc1"></a><h1>Heading 1</h1>
<a name="toc1_0_0_1"></a><h4>Heading 4</h4>
<a name="toc1_1"><h2>Heading 2</h2>
<a name="toc1_1_0_0_1"><h5>Heading 5</h5>
<a name="toc1_1_0_0_1_1"><h6>Heading 6</h6>
<a name="toc1_2"><h2>Heading 2</h2>
Is this possible with pure XSLT processing?
Lösung
Although this won't quite match your current expected output, you could possible make use of the xsl:number element here:
<xsl:number count="section" level="multiple" />
You would need to combine this with the translate function to replace . with _ though. Try the following XSLT
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="html" indent="yes" encoding="UTF-8"/>
<xsl:template match="/">
<xsl:apply-templates/>
</xsl:template>
<xsl:template match="header">
<xsl:variable name="level" select="count(ancestor-or-self::section)"/>
<xsl:variable name="name">
<xsl:number count="section" level="multiple"/>
</xsl:variable>
<a name="{translate($name, '.', '_')}"/>
<xsl:element name="h{$level}">
<xsl:apply-templates/>
</xsl:element>
</xsl:template>
</xsl:stylesheet>
This would output the following:
<a name="1" /><h1>Heading 1</h1>
<a name="1_1_1_1" /><h4>Heading 4</h4>
<a name="1_2" /><h2>Heading 2</h2>
<a name="1_2_1_1_1" /><h5>Heading 5</h5>
<a name="1_2_2" /><h3>Heading 3</h3>
<a name="1_3" /><h2>Heading 2</h2>
Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow