This is the mail archive of the xsl-list@mulberrytech.com mailing list .


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Re: Combining HTML/FO StyleSheets (Indirection/Abstraction Methods) - Non-Trivial


Hi Peter,

I know that you've got this working, but just to comment on some other
possibilities that you might consider here...

>   <xsl:template name="MakeParagraph">
>     <xsl:param name="contents"/>
>     <p>
>       <xsl:value-of select="$contents"/>
>     </p>
>   </xsl:template>
[snip]
> Notice how the other tags have been stripped out of the result (this
> happens on all three XSLT processors I have - xsltproc,xalan,saxon)

The 'tags' are being stripped out because you are getting the *value*
of the $contents parameter, rather than *copying* the $contents
parameter. The $contents parameter holds a result tree fragment. When
you get the value of a result tree fragment, it's just like getting
the value of a node set containing a root node - you get all the text
nodes in the document, concatenated together. If you followed the
pattern:

<xsl:template name="MakeParagraph">
  <xsl:param name="contents">
  <p>
    <xsl:copy-of select="$contents" />
  </p>
</xsl:template>

then you'd have better luck.

The big problem with this approach is all the copying that's done of
the content of the elements. Creating nodes is an expensive operation,
and if your whole stylesheet is designed in this way then you end up
making copies of copies of copies of copies, where in fact you only
wanted the original.

An alternative would be to have separate templates for getting the
names of the elements you need to create and the attributes that you
want to add to them. For example, you could have:

  <xsl:element name="{$paragraphName}">
    <xsl:call-template name="paragraphAttributes" />
    <xsl:text>Text Here</xsl:text>
    <xsl:element name="{$italicsName}">
      <xsl:call-template name="italicsAttributes" />
      <xsl:text>Italic Text Here </xsl:text>
      <xsl:element name="{$boldName}">
        <xsl:text>Bold Italics Text Here</xsl:text>
      </xsl:element>
      <xsl:text> More Just Italic Text Here</xsl:text>
    </xsl:element>
  </xsl:element>

And then for HTML, for example:

<xsl:variable name="paragraphName" select="'p'" />
<xsl:template name="paragraphAttributes" />
<xsl:variable name="italicsName" select="'i'" />
<xsl:template name="italicsAttributes" />
<xsl:variable name="boldName" select="'b'" />
<xsl:template name="boldAttributes" />

Whereas for XSL-FO, you'd have:

<xsl:variable name="paragraphName" select="'fo:block'" />
<xsl:template name="paragraphAttributes" />
<xsl:variable name="italicsName" select="'fo:inline'" />
<xsl:template name="italicsAttributes">
  <xsl:attribute name="font-style">italic</xsl:attribute>
</xsl:template>
<xsl:variable name="boldName" select="'fo:inline'" />
<xsl:template name="boldAttributes">
  <xsl:attribute name="font-weight">bold</xsl:attribute>
</xsl:template>

If you're feeling more adventurous, you could create XML 'templates'
for the different kinds of result that you wanted to generate. For
HTML, you could have:

<templates>
  <template id="paragraph"><p /></template>
  <template id="italics"><i /></template>
  <template id="bold"><b /></template>
</templates>

While for XSL-FO, you could have:

<templates>
  <template id="paragraph"><fo:block /></template>
  <template id="italics"><fo:inline font-style="italic" /></template>
  <template id="bold"><fo:inline font-weight="bold" /></template>
</templates>

And you could access that information in order to create the
paragraph within a single stylesheet:

  <xsl:for-each select="$templates/template[@id = 'paragraph']/*">
    <xsl:copy>
      <xsl:copy-of select="@*" />
      <xsl:text>Text Here</xsl:text>
      <xsl:for-each select="$templates/template[@id = 'italics']/*">
        <xsl:copy>
          <xsl:copy-of select="@*" />
          <xsl:text>Italic Text Here </xsl:text>
          <xsl:for-each select="$templates/template[@id = 'bold']/*">
            <xsl:copy>
              <xsl:copy-of select="@*" />
              <xsl:text>Bold Italics Text Here</xsl:text>
            </xsl:copy>
          </xsl:for-each>
          <xsl:text> More Just Italic Text Here</xsl:text>
        </xsl:copy>
      </xsl:for-each>
    </xsl:copy>
  </xsl:for-each>

Or you could use it to create another stylesheet.

Another possibility, of course, is to create some an XML 'template'
for the paragraph that you want to create:

  <paragraph>
    <xsl:text>Text Here</xsl:text>
    <italics>
      <xsl:text>Italic Text Here </xsl:text>
      <bold>
        <xsl:text>Bold Italics Text Here</xsl:text>
      </bold>
      <xsl:text> More Just Italic Text Here</xsl:text>
    </italics>
  </paragraph>

And run that XML through a transformation to create an XSLT stylesheet
for whatever language you need. The HTML version might look like:

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

<xsl:template match="paragraph">
  <p><xsl:apply-templates /></p>
</xsl:template>

<xsl:template match="italic">
  <i><xsl:apply-templates /></i>
</xsl:template>

<xsl:template match="bold">
  <b><xsl:apply-templates /></b>
</xsl:template>

And for the XSL-FO:

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

<xsl:template match="paragraph">
  <fo:block><xsl:apply-templates /></fo:block>
</xsl:template>

<xsl:template match="italic">
  <fo:inline font-style="italic"><xsl:apply-templates /></fo:inline>
</xsl:template>

<xsl:template match="bold">
  <fo:inline font-weight="bold"><xsl:apply-templates /></fo:inline>
</xsl:template>

The resulting XSLT stylesheet could be used to transform your actual
XML data. In effect, this means creating stylesheets that map from a
common document structure to HTML and to XSL-FO.

Anyway, those are some possibilities...

Cheers,

Jeni

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


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


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]