Just curious - why are you processing input as string instead of tree?
xslt is not text processing language, it's intended for tree transformations.
I believe this string processing example is a very convolute analogue of 3 simple xslt templates:


<xsl:template match="b">
        <fo:block><xsl:apply-templates/></fo:block>
</xsl:template>
<xsl:template match="i">
        <fo:inline><xsl:apply-templates/></fo:inline>
</xsl:template>
<xsl:template match="u">
        <fo:inline 
text-decoration="underline"><xsl:apply-templates/></fo:inline>
</xsl:template>

Moreover, these templates has advantage over string processing - they are really build output tree by elements, while you are just outputting string values like "<b>foo</b>", that's why fop doesn't see element b here - it's just text node holding *characters* '<', 'b', '>', 'f' etc. This string has to be parsed by xml parser in order to be tree or sax events, that is particular reason you cannot avoid transformation to string and reparsing using this technique.
The only reason for using this string-oriented stuff is ill-formed input, like html, but you can use 1) tidy software to get xhtml, 2) html parser (apache has one, libxml is able to parse html also).


Willem-Jan van den Bichelaer wrote:
Hi,

The problem is when we use our template to filter HTML style codes (e.g.
<br>,<b>,<i><u>), FOP does not do what we want it to do.
We use the following template to achieve this:

<xsl:template name="filter-html">
<xsl:param name="in-string"/>
<xsl:variable name="html-breaks" select="'&lt;br&gt;'"/>
<xsl:variable name="bold-begin" select="'&lt;b&gt;'"/>
<xsl:variable name="bold-end" select="'&lt;/b&gt;'"/>
<xsl:variable name="italic-begin" select="'&lt;i&gt;'"/>
<xsl:variable name="italic-end" select="'&lt;/i&gt;'"/>
<xsl:variable name="underline-begin" select="'&lt;u&gt;'"/>
<xsl:variable name="underline-end" select="'&lt;/u&gt;'"/> <xsl:choose>


      <xsl:when test="contains($in-string, $html-breaks)">
         <xsl:call-template name="filter-html">
             <xsl:with-param name="in-string">
               <xsl:value-of select="substring-before($in-string,
$html-breaks)"/>
               <fo:block></fo:block>
               <fo:block><xsl:value-of select="substring-after($in-string,
$html-breaks)"/></fo:block>
             </xsl:with-param>
         </xsl:call-template>
      </xsl:when>

      <xsl:when test="contains($in-string, $bold-begin)">
         <xsl:variable name="bold-string">
            <fo:inline font-weight="bold"><xsl:value-of
select="substring-before(substring-after($in-string, $bold-begin),
$bold-end)"/></fo:inline>
         </xsl:variable>
         <xsl:call-template name="filter-html">
             <xsl:with-param name="in-string">
               <xsl:value-of select="substring-before($in-string,
$bold-begin)"/>
               <xsl:if test="contains(substring-after($in-string,
$bold-begin), $bold-end)">
                  <fo:inline font-weight="bold"><xsl:value-of
select="substring-before(substring-after($in-string, $bold-begin),
$bold-end)"/></fo:inline>
               </xsl:if>
               <xsl:value-of select="substring-after($in-string,
$bold-end)"/>
            </xsl:with-param>
         </xsl:call-template>
      </xsl:when>

      <xsl:when test="contains($in-string, $italic-begin)">
         <xsl:variable name="italic-string">
            <xsl:if test="contains(substring-after($in-string,
$italic-begin), $italic-end)">
               <fo:inline font-style="italic"><xsl:value-of
select="substring-before(substring-after($in-string, $italic-begin),
$italic-end)"/></fo:inline>
            </xsl:if>
         </xsl:variable>
         <xsl:call-template name="filter-html">
             <xsl:with-param name="in-string"><xsl:value-of
select="substring-before($in-string, $italic-begin)"/><xsl:value-of
select="$italic-string"/><xsl:value-of select="substring-after($in-string,
$italic-end)"/></xsl:with-param>
         </xsl:call-template>
      </xsl:when>

      <xsl:when test="contains($in-string, $underline-begin)">
         <xsl:variable name="underline-string">
            <xsl:if test="contains(substring-after($in-string,
$underline-begin), $underline-end)">
               <xsl:value-of select="substring-before($in-string,
$underline-begin)"/>
               <fo:inline text-decoration="underline"><xsl:value-of
select="substring-before(substring-after($in-string, $underline-begin),
$underline-end)"/></fo:inline>
            </xsl:if>
         </xsl:variable>
         <xsl:call-template name="filter-html">
             <xsl:with-param name="in-string"><xsl:value-of
select="substring-before($in-string, $underline-begin)"/><xsl:value-of
select="$underline-string"/><xsl:value-of
select="substring-after($in-string, $underline-end)"/></xsl:with-param>
         </xsl:call-template>
      </xsl:when>

      <xsl:otherwise>
         <xsl:value-of select="$in-string"/>
      </xsl:otherwise>
   </xsl:choose>
</xsl:template>

But somehow we don't see anything in the result while running FOP. That's
why we used CDATA sections. We then used let's say saxon for transforming
the xml into fo-codes, and the gave the fo-file to FOP. Now FOP gives the
result we want, so bold text in the FO language.

I hope this clarifies the matter a bit.

Greetings,

Willem




-- Oleg Tkachenko Multiconn International Ltd, Israel



Reply via email to