[xsl] How to call a template that can generate a file name from an element

Subject: [xsl] How to call a template that can generate a file name from an element
From: Ian Lang <ianplang@xxxxxxxxx>
Date: Tue, 13 Jan 2004 16:06:45 -0800 (PST)
First a little back ground.  What I am trying to do is
create and XSL transform that can create an HTML view
of and XML file.  I need to create multiple HTML files
so I can create a frame based navigation / content
page (the inspiration is Java Doc - with left hand
navigation frames and right hand content frame). 
Below I have a simplified sample xml and a stripped
down xslt file to show my problem.
 
I have some XSLT sheets that generate content and now
I am trying to create a style sheet that will create
the XXXindex.html file that will hold the navigation
and content frames.  One thing I am going to need is
to generate a file name given an element (so I can
create <a href="XXXcontent.html"> nodes for
navigation.  At the moment I am just going to use the
name of the element for the file name but I know
eventually I will need to change this to handle some
combination of an element's id and name (exactly how
is yet to be determined).  I wrote the template (see
below) using @name to construct the file name as a
test.  This created the HTML I wanted.  Next I tried
to refactor to encapsulate the file name generation so
I can change what parts of an element are used to
generate file names in one place.  But I cannot seem
to figure out how to pass an element to the template.

The simplified xml file and a stripped down xslt file
(sorry it is still quite long) show my problem.  I am
creating the file name like this right now:
  <xsl:variable name="rootName" select="@name"/>
  <redirect:write select="concat($outputDir, $fileSep,
$rootName, '_index', '.html')">

But I want to use the template named
createBaseFrameFileName so that I can change from
concat (...@name, ...) to concat (..., @name, @id,
...) or what ever in the future.  What I am getting
from the message "The value of generateName is: " is
25 new line's not the name of the element.
 
Any help / advice would be appreciated.
 
Thanks,
 
IL
 
Example files:
TestFileCabinet.xml
---8<---
<?xml version="1.0" encoding="UTF-8"?>
<cabinet name="Test Cabinet">
<content type="folder" name="Folder1">
<content type="folder" name="FolderA">
<content type="file" name="File1">
</content>
</content>
<content type="folder" name="FolderB">
<content type="folder" name="FolderBA">
<content type="file" name="File2">
</content>
</content>
<content type="file" name="File3">
</content>
<content type="file" name="File4">
</content>
</content>
</content>
<content type="folder" name="Folder2">
<content type="file" name="File5">
</content>
</content>
<content type="folder" name="Folder3">
</content>
<content type="file" name="File6">
</content>
</cabinet>
--->8---
 
The style sheet
---8<---
<?xml version="1.0"?>
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"; 
                             
xmlns:redirect="org.apache.xalan.xslt.extensions.Redirect"

                             
extension-element-prefixes="redirect">

  <xsl:output method="html"/>

  <!-- Required parameters -->
  <xsl:param name="outputDir"/> <!-- Location for root
of output -->
  
  <!-- Variables -->
  <xsl:variable name="fileSep">\</xsl:variable>
  <xsl:variable name="newLine">
  <xsl:text>
  </xsl:text>
  </xsl:variable>

  <!-- Main template - currently this expects that
there will be a single root object, either a cabinet
or a folder -->
  <xsl:template match="/">
    <xsl:apply-templates
select="cabinet|content[@type='folder']"
mode="CreateBaseFrame">
      <xsl:with-param name="title"><xsl:value-of
select="@name"/></xsl:with-param>
      <xsl:with-param
name="description"><xsl:text>Contents of file cabinet
"</xsl:text><xsl:value-of
select="@name"/><xsl:text>".</xsl:text></xsl:with-param>
    </xsl:apply-templates>
    <!-- Other apply template calls will do work of
creating the HTML to be displayed in the frames  -->
  </xsl:template>
  
  <xsl:template name="createBaseFrameFileName">
    <xsl:param name="element"/>
    
    <xsl:value-of select="$element[@name]"/>
 <!--    <xsl:value-of select="concat($outputDir,
$fileSep, $element[@name], '_index', '.html')"/> -->
  </xsl:template>

  <!-- Generate the top level html file which sets up
the frames -->
  <xsl:template match="cabinet|content"
mode="CreateBaseFrame">
    <xsl:param name="title"/>
    <xsl:param name="generator" select="'Our
Generator'"/>
    <xsl:param name="description" select="''"/>
    <xsl:param name="keywords" select="''"/>

    <xsl:variable name="generatedName">
      <xsl:call-template
name="createBaseFrameFileName">
        <xsl:with-param name="element" select="."/>
      </xsl:call-template>
    </xsl:variable>

    <xsl:message terminate="no">
      <xsl:text>The value of generatedName is:
"</xsl:text>
      <xsl:value-of select="$generatedName"/>
      <xsl:text>"</xsl:text>
    </xsl:message>

    <xsl:variable name="rootName" select="@name"/>
    
    <redirect:write select="concat($outputDir,
$fileSep, $rootName, '_index', '.html')">
	
	    <html>
	      <head>
	        <title><xsl:text>Contents of:
</xsl:text><xsl:value-of select="$title"/></title>
	        <xsl:if test="$generator != ''">
	          <meta><xsl:attribute
name="generator"><xsl:value-of
select="$generator"/></xsl:attribute></meta>
	        </xsl:if>
	        <xsl:if test="$description != ''">
	          <meta><xsl:attribute
name="description"><xsl:value-of
select="$description"/></xsl:attribute></meta>
	        </xsl:if>
	        <xsl:if test="$keywords != ''">
	          <meta><xsl:attribute
name="keywords"><xsl:value-of
select="$keywords"/></xsl:attribute></meta>
	        </xsl:if>
	      </head>
	      <frameset cols="20%,80%">
	        <frameset rows="30%,70%">
	          <frame
name="packageListFrame"><xsl:attribute
name="src"><xsl:value-of
select="$rootName"/><xsl:text>packagelist.html</xsl:text></xsl:attribute></frame>
	          <frame name="packageFrame"><xsl:attribute
name="src"><xsl:value-of
select="$rootName"/><xsl:text>allelements.html</xsl:text></xsl:attribute></frame>
	        </frameset>
	        <frame src="overview-summary.html"
name="classFrame"/>
	      </frameset>
	      <noframes>
	        <h2>Frame Support Expected</h2>
	        <p>This document has been designed to use the
HTML Frames feature. If you see this message it means
your browser does not support frames; 
	          <br/>link to
	          <a><xsl:attribute name="href"><xsl:value-of
select="$rootName"/><xsl:text>overview-summary.html</xsl:text></xsl:attribute>
	          Non-frame version instead.</a></p>
	      </noframes>
	    </html>
	    
	  </redirect:write>
	    
  </xsl:template>

</xsl:stylesheet>
--->8---

Command line (assuming a xalan.cmd that does the right
java <classname> stuff and a sub directory
CabinetTest)
---8<---
D:\XSLTWork\>xalan -in TestFileCabinet.xml -xsl
CabinetFrameTest.xslt -param outputDir
"D:\XSLTWork\CabinetTest"
--->8---


__________________________________
Do you Yahoo!?
Yahoo! Hotjobs: Enter the "Signing Bonus" Sweepstakes
http://hotjobs.sweepstakes.yahoo.com/signingbonus

 XSL-List info and archive:  http://www.mulberrytech.com/xsl/xsl-list


Current Thread