Dc Redwing
Dc Redwing

Reputation: 1791

XSL hyperlinks on the html page

I am studying XSL and I have question about generating bidirectional hyperlinks in one HTML file.

For example, we have

<person id="first">
-<name>Bob</name>
-<age>19<age>
<person id="second">
-<name>smith</name>
-<age>12<age>
<person id="third">
-<name>Lisa</name>
-<age>30<age>

in the XML file, and I would like create 3 hyperlinks on one HTML page with XSLT.

For example, on the top of the HTML page, we have three links:

  1. Bob
  2. Smith
  3. Lisa

And on the bottom of the same HTML page, we have three links:

  1. Bob
  2. Smith
  3. Lisa

If user clicks 1. Bob, we go to 4. Bob on the bottom of the page (1. Bob <-> 4. Bob)

If user clicks 4. Bob, we go to 1. Bob on the bottom of the page

If user clicks 2. Smith, we go to 5. Smith the bottom of the page (5. Smith <-> 5.Smith)

If user clicks 5. Smith, we go to 2. Smith the bottom of the page

I tried to use <a id="some value"> </a>

However, it didn't really work.

Can anyone give an example??

Thanks.

Upvotes: 0

Views: 1474

Answers (2)

Ian Roberts
Ian Roberts

Reputation: 122364

This isn't necessarily an XSLT question, you simply need to generate the appropriate <a id="link1" href="#link4">...</a> and vice-versa. For example the top links could be

<xsl:for-each select="person">
  <a id="top_{@id}" href="#bottom_{@id}">
    <xsl:value-of select="name"/>
  </a>
</xsl:for-each>

Upvotes: 1

Tim C
Tim C

Reputation: 70598

If you want to navigate to an anchor tag in your page, you will need another link with the href attribute set to the appropriate value. For example, if you anchor tag was this:

<a id="first">Bob</a>

Then your link would be like this

<a href="#first">Bob</a>

In your case, you want anchors linking to each other, so both a elements would have both an id and href

<a id="first_top" href="#first_bottom">Bob</a>
<a id="first_bottom" href="#first_top">Bob</a>

One way to code your XSLT to do this is have two templates matching the people elements, but with a mode attribute to distinguish between them

Try this XSLT for example

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
   <xsl:output method="html" indent="yes"/>
   <xsl:template match="/people">
      <html>
         <body>
            <xsl:apply-templates select="person" mode="top"/>
            <p>
               Some content in the middle
            </p>
            <xsl:apply-templates select="person" mode="bottom"/>
         </body>
      </html>
   </xsl:template>

   <xsl:template match="person" mode="top">
      <p>
         <a id="{@id}_top" href="#{@id}_bottom">
            <xsl:value-of select="name" />
         </a>
      </p>
   </xsl:template>

   <xsl:template match="person" mode="bottom">
      <p>
         <a id="{@id}_bottom" href="#{@id}_top">
            <xsl:value-of select="name" />
         </a>
      </p>
   </xsl:template>
</xsl:stylesheet>

This outputs the following (assuming you have well-formed XML with a root element, and all tags closed)

<html>
<body>
<p><a id="first_top" href="#first_bottom">Bob</a></p>
<p><a id="second_top" href="#second_bottom">smith</a></p>
<p><a id="third_top" href="#third_bottom">Lisa</a></p>
<p>Some content in the middle</p>
<p><a id="first_bottom" href="#first_top">Bob</a></p>
<p><a id="second_bottom" href="#second_top">smith</a></p>
<p><a id="third_bottom" href="#third_top">Lisa</a></p>
</body>
</html>

If you wanted to avoid having two separate templates for matching person elements, you could pass parameters to the template instead to distinguish between top and bottom. This XSLT would also work

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
   <xsl:output method="html" indent="yes"/>
   <xsl:template match="/people">
      <html>
         <body>
            <xsl:apply-templates select="person">
                <xsl:with-param name="idpos" select="'top'" />
                <xsl:with-param name="hrefpos" select="'bottom'" />
            </xsl:apply-templates>
            <p>
               Some content in the middle
            </p>
            <xsl:apply-templates select="person">
                <xsl:with-param name="idpos" select="'bottom'" />
                <xsl:with-param name="hrefpos" select="'top'" />
            </xsl:apply-templates>
         </body>
      </html>
   </xsl:template>

   <xsl:template match="person">
      <xsl:param name="idpos" />
      <xsl:param name="hrefpos" />
      <p>
         <a id="{@id}_{$idpos}" href="#{@id}_{$hrefpos}">
            <xsl:value-of select="name" />
         </a>
      </p>
   </xsl:template>
</xsl:stylesheet>

Upvotes: 3

Related Questions