views:

111

answers:

3

I have this XSLT:

<xsl:strip-space elements="*" />
<xsl:template match="math">
    <img class="math">
        <xsl:attribute name="src">http://latex.codecogs.com/gif.latex?&lt;xsl:value-of
            select="text()" /></xsl:attribute>
    </img>
</xsl:template>

Which is being applied to this XML (notice the line break):

<math>\text{average} = \alpha \times \text{data} + (1-\alpha) \times
    \text{average}</math>

Unfortunately, the transform creates this:

<img
    class="math"
    src="http://latex.codecogs.com/gif.latex?\text{average} = \alpha \times \text{data} + (1-\alpha) \times&#10;&#9;&#9;&#9;&#9;&#9;\text{average}" />

Notice the whitespace character literals. Although it works, it's awfully messy. How can I prevent this?

A: 

I am not sure how you are generating the text. But there are two ways:

  1. You can use the xsl:strip-space element that is available in XSLT.

  2. If you generate the text during XSLT process, then another way to achieve will be to make use of string process methods: normalize-space and replace methods.

Abdel Olakara
+1  A: 

The normalize-space function strips leading and trailing whitespace and replaces sequences of whitespace characters by a single space. With no parameters, it will operate on the string value of the context node.

<xsl:template match="math">
    <img class="math">
        <xsl:attribute name="src">http://latex.codecogs.com/gif.latex?&lt;xsl:value-of select="normalize-space()" /></xsl:attribute>
    </img>
</xsl:template>

Also your stylesheet can be simplified by using an attribute value template instead of xsl:attribute.

<xsl:template match="math">
    <img class="math" src="http://latex.codecogs.com/gif.latex?{normalize-space()}" />
</xsl:template>
Lachlan Roche
This does not solve the problem as there are still some mid-spaces left. See my answer for a solution that really solves the problem.
Dimitre Novatchev
A: 

It is not sufficient to use the normalize-space() function as it is leaving mid-spaces!

Here is a simple and complete solution:

<xsl:stylesheet version="1.0"
 xmlns:xsl="http://www.w3.org/1999/XSL/Transform"&gt;
 <xsl:output omit-xml-declaration="yes"/>
 <xsl:strip-space elements="*" />

 <xsl:template match="math">
    <img class="math">
        <xsl:attribute name="src">http://latex.codecogs.com/gif.latex?&lt;xsl:value-of
            select="translate(.,' &#9;&#10;', '')" /></xsl:attribute>
    </img>
 </xsl:template>
</xsl:stylesheet>

When this transformation is applied on the provided XML document:

<math>\text{average} = \alpha \times \text{data} + (1-\alpha) \times
    \text{average}</math>

the wanted, correct result is produced:

<img class="math" src="http://latex.codecogs.com/gif.latex?\text{average}=\alpha\times\text{data}+(1-\alpha)\times\text{average}" />

Do note:

  1. The use of the XPath 1.0 translate() function to strip off all unwanted characters.

  2. There is no need to use the replace() function here -- it may not be possible to use it, because it is only available in XPath 2.0.

Dimitre Novatchev
Oddly enough, I stumbled across a similar solution myself: `translate(normalize-space(), ' ', '')`. Although I've now realized that I probably want to URL-escape the spaces to `%20`, rather than remove them. Can `translate` be used for that purpose?
Eric
@Eric: No, `translate()` only substitutes char for char or eats a char. Please, ask another question and I'll show how to replace a space with %20. If you have XSLT 2.0 you can use the XPath 2.0 `replace()` function to do this. In XSLT 1.0 there are other ways.
Dimitre Novatchev
In XSLT 2.0, I could use `url-encode()`. But I can't use XSLT 2.0.
Eric