Re: [xsl] dynamically generating css

Subject: Re: [xsl] dynamically generating css
From: Jeni Tennison <jeni@xxxxxxxxxxxxxxxx>
Date: Tue, 31 Aug 2004 14:05:31 +0100
Hi Bruce,

> I'm making progress on this, but I'm stuck in only get one element
> output.

The problem here is that the second element that you want to output
is nested two levels within the <cs:reftype> element, but you're only
selecting the *children* of the <cs:reftype> element with:

  <xsl:for-each select="$style/*[@font-style | @font-weight]">
    ...
  </xsl:for-each>

What I suggest is that you turn your stylesheet inside-out. Instead of
working from the top down to the elements that you want to create
styles for, work from those elements up to their ancestor <cs:reftype>
element in order to create the CSS class names.

Something like:

<xsl:template match="cs:citationstyle" name="css">
  <xsl:apply-templates select="cs:*" mode="css" />
</xsl:template>

<xsl:template match="cs:reftype//cs:*" mode="css">
  <xsl:variable name="styles" as="attribute()*"
                select="@* except (@before, @after)" />
  <xsl:if test="$styles">
    <xsl:text>..</xsl:text>
    <!-- apply templates in css-name mode to get the class name -->
    <xsl:apply-templates select="." mode="css-name" />
    <xsl:text> {&#xA;</xsl:text>
    <xsl:apply-templates select="$styles" mode="css" />
    <xsl:text>}&#xA;&#xA;</xsl:text>
  </xsl:if>
  <xsl:apply-templates select="cs:*" mode="css" />
</xsl:template>

<!-- To get the class name for an element, get the class name for its
     parent, add a "-" as a separator, and then add the name of the
     element itself. -->
<xsl:template match="cs:*" mode="css-name">
  <xsl:apply-templates select=".." mode="css-name" />
  <xsl:text>-</xsl:text>
  <xsl:value-of select="name()" />
</xsl:template>

<!-- The base class name is the value of the name attribute on the
     <cs:reftype> element. When we get to the <cs:reftype> element, we
     stop recursing up the tree. -->
<xsl:template match="cs:reftype" mode="css-name">
  <xsl:value-of select="@name" />
</xsl:template>

<xsl:template match="@*" mode="css">
  <xsl:value-of select="name()" />
  <xsl:text>: </xsl:text>
  <xsl:value-of select="." />
  <xsl:text>;&#xA;</xsl:text>
</xsl:template>

Note that using <xsl:text> and &#xA; (the newline character) allows
you to control what whitespace makes it to the output, which means you
can make the code more readable: you don't have to actually insert a
newline to create a newline, or avoid indenting your code because you
don't want whitespace to appear in the output.

Cheers,

Jeni

---
Jeni Tennison
http://www.jenitennison.com/

Current Thread