Jokab Jokab - 4 months ago 13
HTML Question

XSLT handling same XML node in different ways in different places of the HTML document

I want to have a template for creating a table of contents at the top of my HTML document, and I want to be able to click each item in this table to get to more detailed information about it, that is, it jumps to the appropriate detailed section further down in the document.

Sort of like:


Table of contents:

Node1 (clicking this takes you to the bolded Node1 below)

Node2

Node3

other stuff ... ...

Node1

Description: blah

Content: 1.55

Version: 1.55


Rough XSLT code:

// create table of contents
<table border="1">
<tr bgcolor="#9acd32">
<th style="text-align:left">Name</th>
</tr>
<xsl:for-each select="">
<xsl:apply-templates select="my_node"/>
</xsl:for-each>

// do other stuff

// create detailed view (code omitted because I don't know how yet)

// template for node
<xsl:template match="my_node">
<tr>
<td><xsl:value-of select="../@name"/></td>
</tr>
</xsl:template>


My problem is that I want to handle this node twice but in different places in my code, one where I just grab the name and one where I grab all its information. As I understand it, having one template for each node is the preferred practice in XSLT. How can I achieve what I am describing here?

Do I pass sort of a boolean parameter to determine which action to take inside the template? Or write a template for a parent node and traverse down to the name in the first case? I'm not sure I like either of those.

Answer

Use modes. Roughly:

<xsl:template match="/">

    <!--  create table of contents -->
    <table border="1">
        <tr bgcolor="#9acd32">
            <th style="text-align:left">Name</th>
        </tr>
        <xsl:apply-templates select="my_node" mode="toc"/>
    </table>

    <!-- do other stuff -->

    <!-- create detailed view  -->
    <h1>Details</h1>
    <xsl:apply-templates select="my_node"/>
</xsl:template>

<xsl:template match="my_node" mode="toc">
    <tr>
        <td><xsl:value-of select="../@name"/></td>
    </tr>
</xsl:template>

<xsl:template match="my_node">
    <!-- whatever is required for detailed view -->
</xsl:template>

P.S. Be careful about mixing xsl:for-each with xsl:apply templates. In most cases, you want to use either one or the other.

Comments