Re: [xsl] RE: Will this work?

Subject: Re: [xsl] RE: Will this work?
From: Geert Josten <Geert.Josten@xxxxxxxxxxx>
Date: Tue, 30 Nov 2004 15:01:32 +0100
I promissed an example. Well, here it is..

Last week I was working on a Cocoon webapp that takes 'xhtml' templates and combines them with xml data to generate html pages. I invented a new namespace with prefix tp to which a stylesheet responds by replacing these instructions by xsl instructions. The whole template file itself is kind of inserted into a xsl:template match="/" to make it work.

the tp:insert-param instruction was actually intended to access a Cocoon or http url to get dynamic parameters, but it can be used to access a more static xml file just as well..

I am inserting a template and the meta stylesheet below. Apply the stylesheet to the template and try to identify how the resulting stylesheet matches to the template.

Grtz,
Geert

wellformed HTML template .tpl:

<?xml version="1.0" encoding="utf-8"?>
<HTML xmlns:tp="http://www.daidalos.nl/schemas/template/1.0";>
  <HEAD>
    <!-- Generated by javadoc on Tue Sep 21 16:38:10 GMT+01:00 2004-->
    <tp:comment>Generated by</tp:comment>
    <TITLE>
      <tp:insert-param name="name" default="XSLdoc" />
      <tp:text> (</tp:text>
      <tp:insert-param name="version" default="1.0" />
      <tp:text>) - Package</tp:text>
    </TITLE>
    <META NAME="keywords">
       <tp:attribute name="CONTENT">
         <tp:text>Package, </tp:text>
         <tp:insert-param name="/classes/@package-path" />
       </tp:attribute>
    </META>
    <LINK REL ="stylesheet" TYPE="text/css" TITLE="Style">
      <tp:attribute name="HREF">
        <tp:revert-path select="translate(/classes/@package-path, '.', '/')" />
        <tp:text>javadoc.css</tp:text>
      </tp:attribute>
    </LINK>
  </HEAD>

  <BODY BGCOLOR="white">
    <FONT size="+1" CLASS="FrameTitleFont">
      <A HREF="package-summary.html" target="classFrame">
        <tp:value select="/classes/@package-path" />
      </A>
    </FONT>

    <TABLE BORDER="0" WIDTH="100%" SUMMARY="">
      <TR>
        <TD NOWRAP="">
          <FONT size="+1" CLASS="FrameHeadingFont">
            Classes
          </FONT>
          <BR />
          <FONT CLASS="FrameItemFont">
            <tp:for-each select="/classes/class">
              <A target="classFrame">
                <tp:attribute name="title">
                  <tp:text>class in </tp:text>
                  <tp:value select="../@package-path" />
                </tp:attribute>
                <tp:attribute name="HREF">
                  <tp:value select="translate(@relative-path, '.', '/')" />
                  <tp:text>.</tp:text>
                  <tp:value select="@type" />
                  <tp:text>.html</tp:text>
                </tp:attribute>
                <tp:value select="@relative-path" />
                <tp:text> (</tp:text>
                <tp:value select="@type" />
                <tp:text>)</tp:text>
              </A>
              <BR />
            </tp:for-each>
          </FONT>
        </TD>
      </TR>
    </TABLE>

  </BODY>
</HTML>

template2xsl.xsl:
<?xml version="1.0" encoding="UTF-8"?>

<!-- $Id$ -->

<xsl:stylesheet version="1.0"
    xmlns:xsl="http://www.w3.org/1999/XSL/Transform";
    xmlns:tp-xsl="http://www.w3.org/1999/XSL/TransformAlias";
    xmlns:tp="http://www.daidalos.nl/schemas/template/1.0";
    exclude-result-prefixes="tp"
>

<!--+ ==============================================================
    | parameters
    +-->

<xsl:namespace-alias stylesheet-prefix="tp-xsl" result-prefix="xsl"/>

  <xsl:output method="xml"
    version="1.0" encoding="utf-8" indent="yes" />

<!--+ ==============================================================
    | default templates
    +-->

  <xsl:template match="@*|node()">
    <xsl:copy-of select="." />
  </xsl:template>

  <xsl:template match="*">
    <xsl:element name="{name()}">
      <xsl:apply-templates select="@*|node()" />
    </xsl:element>
  </xsl:template>

<xsl:template match="tp:*">
<xsl:message terminate="yes">
Unknown or incorrect template instruction <xsl:value-of select="name()" /> within context <xsl:value-of select="name(parent::*)"/>
</xsl:message>
</xsl:template>


<!--+ ==============================================================
    | root template
    +-->

  <xsl:template match="/">
    <tp-xsl:stylesheet version="1.0">

      <tp-xsl:output method="xml"
        version="1.0" encoding="utf-8" indent="yes" />

      <tp-xsl:param name="parameter-url" />
      <tp-xsl:param name="parameters" select="document($parameter-url)/*" />

      <tp-xsl:template match="/">
        <xsl:apply-templates select="@*|node()" />
      </tp-xsl:template>

<tp-xsl:template name="revert-path">
<tp-xsl:param name="path" />
<tp-xsl:param name="count" select="string-length($path) - string-length(translate($path, '/', ''))" />


        <tp-xsl:if test="$count > 0">
          <tp-xsl:text>../</tp-xsl:text>
          <tp-xsl:call-template name="revert-path">
            <tp-xsl:with-param name="path" select="$path" />
            <tp-xsl:with-param name="count" select="$count - 1" />
          </tp-xsl:call-template>
        </tp-xsl:if>
      </tp-xsl:template>

    </tp-xsl:stylesheet>
  </xsl:template>

<!--+ ==============================================================
    | templates
    +-->

  <xsl:template match="tp:insert-param[@name]">
    <tp-xsl:variable name="param-name-{generate-id()}" select="'{@name}'" />
    <tp-xsl:variable name="value" select="$parameters/*[name() = $param-name-{generate-id()}]" />

    <tp-xsl:choose>
      <tp-xsl:when test="$value">
        <tp-xsl:value-of select="$value" />
      </tp-xsl:when>
      <tp-xsl:otherwise>
        <xsl:value-of select="@default" />
      </tp-xsl:otherwise>
    </tp-xsl:choose>
  </xsl:template>

  <xsl:template match="tp:value[@select]">
    <tp-xsl:value-of select="{@select}">
      <xsl:if test="@escape = 'no'">
        <xsl:attribute name="disable-output-escaping">yes</xsl:attribute>
      </xsl:if>
    </tp-xsl:value-of>
  </xsl:template>

  <xsl:template match="tp:revert-path[@select]">
    <tp-xsl:call-template name="revert-path">
      <tp-xsl:with-param name="path" select="{@select}" />
    </tp-xsl:call-template>
  </xsl:template>

  <xsl:template match="tp:text">
    <tp-xsl:text>
      <xsl:if test="@escape = 'no'">
        <xsl:attribute name="disable-output-escaping">yes</xsl:attribute>
      </xsl:if>
      <xsl:value-of select="." />
    </tp-xsl:text>
  </xsl:template>

  <xsl:template match="tp:for-each[@select]">
    <tp-xsl:for-each select="{@select}">
      <xsl:apply-templates select="node()" />
    </tp-xsl:for-each>
  </xsl:template>

  <xsl:template match="tp:attribute[@name]">
    <tp-xsl:attribute name="{@name}">
      <xsl:apply-templates select="node()" />
    </tp-xsl:attribute>
  </xsl:template>

  <xsl:template match="tp:comment">
    <tp-xsl:comment>
      <xsl:apply-templates select="node()" />
    </tp-xsl:comment>
  </xsl:template>

  <xsl:template match="tp:copy[@select]">
    <tp-xsl:variable name="copy-{generate-id(.)}" select="{@select}" />
    <tp-xsl:choose>
      <tp-xsl:when test="$copy-{generate-id(.)}">
        <tp-xsl:copy-of select="$copy-{generate-id(.)}" />
      </tp-xsl:when>
      <tp-xsl:otherwise>
        <xsl:apply-templates select="tp:fallback/node()" />
      </tp-xsl:otherwise>
    </tp-xsl:choose>
  </xsl:template>

</xsl:stylesheet>

Current Thread