tags:

views:

326

answers:

5

in IE (maybe FF too, but not sure) the following snippet from my XSL stylesheet...

<td>
  <xsl:element name="img">
    <xsl:attribute name="src">
      <xsl:value-of select="image" />
    </xsl:attribute>
  </xsl:element>
</td>

generates the following XHTML code...

<td><img src="
    someimage.jpg"></td>

this new line that it inserts after the src=" is causing issues when later parsing it using the DOM. any ideas?

thanks so much in advance for your help!

+1  A: 

Very weird issue, indeed...

Did you try this?

<xsl:attribute name="src"><xsl:value-of select="image" /></xsl:attribute>
Erlock
+2  A: 

I've tried your XSLT, and indeed I think you should rethink your choice of XSLT processor, cos that shouldn't be happening.

Anyhow, this should fix it:

<xsl:attribute name="src">
  <xsl:text/><xsl:value-of select="image" /><xsl:text/>
</xsl:attribute>

EDIT:

Try this

<td>
    <img src="{image}"/>
</td>

If that doesn't work as well, then I am dumbfounded.... perhaps check your data source? Does the input of the XSLT contain:

<image>someimage.ext</image>

or

<image>
    someimage.ext
</image>

If it is the latter, then I think could be the problem in your input rather than your XSLT.

bguiz
you'd think so, but i still have a new line. i must be missing something. with that and the strip-space, i'm still getting a new line. anyhow, i'll keep pounding on it, thanks for your help!
BeachRunnerJoe
@Dr Dork, just ourt of curiosity, I wanna know which XSLT processor you are using.. Neither Saxon nor Xalan have this issue.
bguiz
+2  A: 

I don't know why whitespace nodes in the XSLT are making their way into attribute values, but there's a really simple way to eliminate the problem: use an attribute value template. That lets you get rid of a whole lot of cruft in addition to fixing the actual problem.

Instead of this:

<td>
  <xsl:element name="img">
    <xsl:attribute name="src">
      <xsl:value-of select="image" />
    </xsl:attribute>
  </xsl:element>
</td>

do this:

<td>
  <img src="{image}"/>
</td>
Robert Rossney
+1 for "do this:"
Tomalak
+1  A: 

I agree with Robert that a AVT is a way to go, but I would also suggest throwing a normalize-space() around image as the source xml may have the new line characters:

<td>
  <img src="{normalize-space(image)}"/>
</td>

In my test using xalan 2.7, just doing an AVT did not solve the problem if the source had a new line character:

<image>
   abc.jpg
</image>
alanstroop
No, this won't make the problem go away since AVT is equivalent to <xsl:attribute>/<xsl:value-of>, only shorter. If the newline is in the input data, it stays there.
Tomalak
You must have missed the part about "normalize-space()". That is the key point to my solution. The source is where the new line charcter is.
alanstroop
+5  A: 

In one of the comments (to a now-deleted answer) you said your input looks like this:

<image>
 someimage.jpg</image>

This is where your newline comes from - it is part of the node value and is therefore retained by the XSL processor (it is not "added", as you suspected).

To remove the space, you must modify the node value before you output it, best suited in this case is the normalize-space() function, since URLs do not contain spaces, generally.

<td>
  <img src="{normalize-space(image)}"/>
</td>

If you have any chance, this should be fixed in the process that generates the input XML, since the XML itself is already wrong. If the newline is not part of the data, it should not be there in the first place.

Contrary to what many others here proposed, your XSLT code layout has no influence on the output. All whitespace is stripped from the XSL stylesheet before processing begins, so this:

<td>
  <xsl:element name="img">
    <xsl:attribute name="src">
      <xsl:value-of select="image" />
    </xsl:attribute>
  </xsl:element>
</td>

though unnecessarily verbose, is equivalent to this:

<td>
  <xsl:element name="img"><xsl:attribute name="src"><xsl:value-of select="image" /></xsl:attribute>
  </xsl:element>
</td>

is equivalent to this, as far as output whitespace is concerned:

<td><img src="{image}"/></td>

However, if stray text nodes are in your XSL code, all whitespace around them is retained. This means you should not do this:

<td>
  Stray Text
</td>

Since this would generate a "\n Stray Text\n " text node in the output. Better is:

<td>
  <xsl:text>Contained Text</xsl:text>
</td>

In regard to: "But why does <xsl:strip-space> not work?" I recommend reading Pavel Minaev's answer to exactly this question.

Tomalak
thank you, that worked!
BeachRunnerJoe