Geeks With Blogs
Amusingly MOSS ...It's funny how difficult some stuff is when it really shouldn't be

And I don't mean the Diet Coke of Evil (only one calorie, not evil enough). I spent most of today finding out the most stupid of things.

All I wanted to do was to create a blasted <img /> tag that had its source attribute set dynamically by XSLT.  Seems pretty run-of-the-mill, eh?  Here's the XSLT (I've even replaced the xpath with hard-wired text to simplify the scenario):

<xsl:stylesheet version="1.0" extension-element-prefixes="msxsl" exclude-result-prefixes="msxsl js dl" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:js="urn:custom-javascript" xmlns:msxsl="urn:schemas-microsoft-com:xslt" xmlns:dl="urn:datalist">
  <xsl:output method="xml" version="1.0" omit-xml-declaration="yes" indent="yes" encoding="utf-8"/>
  <xsl:template match="/" xml:space="preserve">
  <div class="sponsorLogo">
    <xsl:element name="img">
     <xsl:attribute name="src">test.gif</xsl:attribute>
   </xsl:element>
  </div>
 </xsl:template>
</xsl:stylesheet>

I fired up my trusty, dusty C# transform method that I've used for quite a while, passed in the XML I want to transform with the above XSLT, and BOOM! I get this .NET runtime error:

Attribute and namespace nodes cannot be added to the parent element after a text, comment, pi, or sub-element node has already been added.

What on earth?!  I've done this sort of thing many, many times, so why now?  Well, here's the reason:

<xsl:template match="/" xml:space="preserve">

It turns out that this attribute tells the XSLT parser to treat the white space I was using to indent/format my xslt as actual text, which makes the above error make a lot more sense.  I stripped out the xml:space="preserve" attribute, and poof, everything worked perfectly.

So, there are really two lessons to be learned here:

  1. xml:space="preserve" treats ANY white space (to include line breaks) as actual text, so don't use it if you plan on making your XSLT readable by any human being.
  2. Don't cut-and-paste an XSLT document from some other system without first being SURE you know what your headers are doing.

What a disaster.  Now, it's time to go home.  Have a good weekend, everyone.

Posted on Friday, May 15, 2009 5:43 PM Other Stuff | Back to top


Comments on this post: XSLT is Pure Evil

# re: XSLT is Pure Evil
Requesting Gravatar...
I always believed that XSLT was an April Fools joke, but apparently some people believed it was meant to be used.
Left by Alain on May 17, 2009 9:50 AM

# re: XSLT is Pure Evil
Requesting Gravatar...
Why not try? <img src="{images/src}" />
Left by Phillip on May 17, 2009 2:59 PM

# re: XSLT is Pure Evil
Requesting Gravatar...
does finding some xlst caveat really call for the sensationalist title?!
Left by Kfir on May 17, 2009 4:02 PM

# re: XSLT is Pure Evil
Requesting Gravatar...
To me it looks as an expected error if you look at it from a streaming perspective, otherwise the xslt transformer would need to buffer the output, which is insane from performance perspective.
Left by David on May 18, 2009 7:53 AM

# re: XSLT is Pure Evil
Requesting Gravatar...
Perhaps "XSLT is Pure Evil" is a sensationalist title from the standpoint of the subject matter being very small in the grand scheme of the awesome things that you can accomplish through the use of XSLT.

However, I feel that the amount of hair I pull out to accomplish those awesome things through XSLT is rarely justified in the long run (especially considering that I don't have that much hair left to pull out in the first place).

Perhaps a better title would be, "XSLT makes me bald(er)."
Left by Adam McKee on May 18, 2009 11:53 AM

# re: XSLT is Pure Evil
Requesting Gravatar...
@Phillip: the attribute value template is the best way to go and produces the desired markup and formatting. Easy to read too.

@OP: The error message is quite clear about where the problem is. Where's the confusion? ;)
Here are two more ways you could have fixed it:

<xsl:element name='img' xml:space="default">
--or--
<xsl:element name='img'><xsl:attribute ...

(but the second way probably needs the IMG markup on one line for the html parse to be happy with it)

Left by steve j on May 18, 2009 5:45 PM

# re: XSLT is Pure Evil
Requesting Gravatar...
@Steve J: Thanks for the tip! I'm mostly on the steep part of the learning XSLT curve at the moment :)
Left by Adam McKee on May 18, 2009 9:15 PM

# re: XSLT is Pure Evil
Requesting Gravatar...
No problem.

Just noticed one more thing: output method='xml'.

The output you show looks like it could be: html, xhtml, or xml that strongly resembles html. If you're really after html, then output='html' *might* fix the issue also.

For future issues be sure to seek out Dave Pawson's XSLT FAQ and books by Michael Kay or Jeni Tennison (if you haven't already). HTH.
Left by steve j on May 19, 2009 9:45 AM

# XML Literals are pure & Good
Requesting Gravatar...
ok....oop purists might not think so, hence they're not in C#. However - for xml translation / manipulation they are the BOMB! i.e. awesome and well worth investigation. Easy to use, powerful and effective. You just gotta use vb.net.
Left by Ben on May 27, 2009 2:21 PM

# re: XSLT is Pure Evil
Requesting Gravatar...
@PM Ben: I'm interested in the VB.Net XSLT components you're talking about - what are they? Where can I find resources on them?
Left by Adam McKee on May 27, 2009 2:28 PM

# re: XSLT is Pure Evil
Requesting Gravatar...
@Adam

check out: http://www.dnrtv.com/default.aspx?showNum=119
Left by Ben on May 28, 2009 10:12 AM

# re: XSLT is Pure Evil
Requesting Gravatar...
Thank you for sharing!!! You've saved me hours of research time I'm sure! What I can't imagine is, WHAT if ANYTHING is xml:space="preserve" used for??
Left by Angie on Apr 01, 2010 6:37 AM

# re: XSLT is Pure Evil
Requesting Gravatar...
THANK YOU SO MUCH! I'm new at this stuff, using some existing xslt, and I never would have figured this out on my own. You've saved me HOURS!
Left by Alicia on Dec 22, 2010 9:14 AM

# re: XSLT is Pure Evil
Requesting Gravatar...
Thank you!! Thank you!!Thank you!!
Left by Anamika Patel on Jun 03, 2011 6:57 AM

# re: XSLT is Pure Evil
Requesting Gravatar...
Hi , my xslt also give error (Attribute and namespace nodes cannot be added to the parent element after a text, comment, pi, or sub-element node has already been added.) on name="onclick" in xslt given below,

<xsl:for-each select="Features/ProductName">
<xsl:variable name="FileName">
<xsl:value-of select="@fileName"/>
</xsl:variable>
<td align="center">

<xsl:choose>

<xsl:when test="@fileName!=''">
<xsl:element name="a">
<xsl:attribute name="onclick">OpenCarrierOutline('<xsl:value-of select="$ServerName"/>','<xsl:value-of select="$FileName"/>');</xsl:attribute>
<xsl:attribute name="href">#</xsl:attribute>
<xsl:value-of select="."/>
</xsl:element>
</xsl:when>

</td>

</xsl:for-each>


please help

Thanks

kapil Gupta
Left by kapil on Jun 20, 2011 6:09 PM

# re: XSLT is Pure Evil
Requesting Gravatar...
This solved my problem - THANK YOU!!!!!!! So freaking ridiculous ...
Left by ncmiami on Dec 22, 2011 12:20 PM

Your comment:
 (will show your gravatar)


Copyright © Adam McKee | Powered by: GeeksWithBlogs.net