xsl-list
[Top] [All Lists]

Extending Xhtml2fo.xsl to handle CLASS attributes

2002-12-17 02:56:39
I'm using Xhtml2fo.xsl (from
http://www.antennahouse.com/XSLsample/XSLsample.htm ; thank you, Antenna
House!) and Apache's FOP to convert my XHTML source to PDF.
 
After some teething problems (mostly solved by finding answers in this
list's archive :-), I now have a Windows script (VBScript) file that:
 
1. Collects many individual XHTML "topic" files into a single XHTML
"publication" file (via XSL), with some additional front matter
2. Transforms the XHTML publication file to FO (using Xhtml2fo.xsl)
3. Converts the FO file to PDF
 
So far so good.
 
Next, I want to extend Xhtml2fo.xsl to handle the CLASS attributes in my
XHTML.  I would appreciate any advice on the best way to implement this.
 
I've already decided that it's probably a good idea to handle CLASS
attributes by extending the existing "process-common-attributes" template,
like this:
 
  <xsl:template name="process-common-attributes">
...
    <xsl:if test="@class">
      <xsl:call-template name="process-class">
        <xsl:with-param name="element" select="local-name()"/>
        <xsl:with-param name="class" select="@class"/>
      </xsl:call-template>
    </xsl:if>
...
  </xsl:template>

But I'm not sure about the best way to implement the new "process-class"
template.
 
I should mention that, in my existing CSS file, I use a combination of
standard CSS attributes (for typographic formatting) and Internet
Explorer-specific "behavior" attributes (these point to VBScript procedures
that dynamically alter the XHTML).  Whatever code I add to Xhtml2fo.xsl to
handle CLASS attributes must be able to not only apply attributes, but also
dynamically alter the result tree in other ways.  (Soon, I plan to replace
these IE-specific behaviors with XSL, but this XHTML-to-PDF process is more
urgent. I *was* creating my PDFs by opening the large "publication" XHTML
file in IE, and then printing to Distiller; but IE now crashes sometimes,
perhaps due to the file size... I never liked this technique anyway.)
 
For example, in my XHTML source, I refer to a "note" class that prefixes a
paragraph or a list with the word "Note:".  For example:
 
<p class="note">This is a note.</p>
 
becomes
 
Note: This is a note.
 
And
 
 
<ul class="note">
<li>First note</li>
...
</ul>
 
 
becomes
 
 
Note:
 
- First note
 
 
Here's my first attempt at a "process-class" template:
 
 
<xsl:template name="process-class">
 
 <xsl:param name="element"/>
 <xsl:param name="class"/>
 
 <xsl:if test="$class='note' and $element='p'">
 
  <fo:inline xsl:use-attribute-sets="b"><xsl:text>Note:
</xsl:text></fo:inline>
 
 </xsl:if>
 
</xsl:template>
 
 
This works, but the thought of coding an <xsl:if> element for each
combination of element name and class has prompted me to write this request
for advice!
 
An alternative that occurred to me was to call named templates, like this:
 
 <xsl:call-template name="concat($element, '-', $class)" />
 
where the templates were defined like this:
 
<xsl:template name="p-note">

<fo:inline xsl:use-attribute-sets="b"><xsl:text>Note:
</xsl:text></fo:inline>
</xsl:template>

 
The trouble with this approach appears to be that calling a named template
that does not exist causes an error.  At least, that's what I interpret this
error (from MSXML) means:
 
this name may not contain the '(' character
 
(this error points to the left parenthesis in the concat function, in the
<xsl:call-template> tag above)
 
Regards,
Graham Hannington
 
P.S.  HAXEP from RenderX (demo at http://www.renderx.com/Demos/HAXEP/ )
looks like it does exactly what I want (well, kind of: converting the rules
in the CSS file to FO is probably smarter than I actually want; I'd settle
for a reasonably elegant way to duplicate those CSS rules in Xhtml2fo.xsl.
(Yes, I realize I just used "elegant" and "duplicate" in the same sentence
;-).

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



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