xsl-list
[Top] [All Lists]

Re: dynamically generating css

2004-08-31 06:05:31
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/*[(_at_)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/



<Prev in Thread] Current Thread [Next in Thread>