views:

2325

answers:

5

When attempting to output an empty textarea element, the .NET XSLT processor collapses the element to its short form. Instead of this:

<textarea id="blah" name="blah"></textarea>

I get this:

<textarea id="blah" name="blah"/>

Which causes many web browsers (including IE and Firefox) to render the rest of the page as if it were the contents of the textarea. This sucks.

I can force the XSLT processor to output both the opening and closing textarea tags if I place something in between like a non-breaking space. But that means I have to do more parsing and validation on the client side to tell when the textarea is "truly" empty. I also have to use JavaScript to remove the extra space so that users don't begin their comments with a blank space.

Does anyone know of a way to force the XSLT processor to render both the opening and closing tags without having to insert dummy content?

+4  A: 

Find your answer via a similar question right here on Stackoverflow.com :-)

Here is further explanation from MSDN.

Chris Ballance
+1  A: 

I you have to use dummy content, this was the xsl:template I used, having just the Line Feed character inside the textarea.

<!-- This prevents empty textarea elements being rendered as singletons in the XHTML output by adding a newline character -->
<xsl:template name="xhtml-textarea-contents">
    <!-- what should be contained in the textarea -->
    <xsl:param name="contents" />

    <xsl:choose>
        <xsl:when test="$contents = ''"><xsl:text>&#x0A;</xsl:text></xsl:when>
        <xsl:otherwise><xsl:copy-of select="$contents" /></xsl:otherwise>
    </xsl:choose>
</xsl:template>
Kevin Hakanson
this is the only thing that worked for me, thanks!
travis
A: 

Chris Ballance had an answer that worked for me. But it's worth noting that I had been using an overload of XslCompiledTransform that output to a stream, like so:

XslCompiledTransform transform = new XslCompiledTransform();
...
MemoryStream stream = new MemoryStream();
transform.Transform(reader, args, stream);

In order to pass the correct settings along, I had to use the overload that accepted an XmlWriter instead.

// using XmlWriter so I can pass the output settings along.
XmlWriter writer = XmlWriter.Create(stream, transform.OutputSettings);
transform.Transform(reader, args, writer);

Microsoft's using a really odd design pattern there.

dthrasher
A: 

I had a similar problem and just realized that if you set the ConformanceLevel of the XmlWriterSettings to Fragment, it eliminates some of the XslCompiledTransform quirks.

FileStream xmlFileStream = File.Create("file.xml");
XslCompiledTransform transform = new XslCompiledTransform();
transform.Load("transform.xsl");
XmlWriterSettings settings = new XmlWriterSettings();
settings.ConformanceLevel = ConformanceLevel.Fragment;
XmlWriter xmlWriter = XmlWriter.Create(xmlFileStream, settings);
transform.Transform(sourceXml, null, xmlWriter);
A: 

If you are generating an xml or html, you can write a newline inside the textarea and then remove it with jquery.

This is an example with jQuery:

<textarea>&#160;<textarea>

<script>
 $(document).ready(function(){
    $('textarea').each(
      function(index){$(this).text('');}
     );
  });
</script>
David García González