XSLT has a facility known as disable-output-escaping (d-o-e) whereby you can write markup as literals. The most common use for d-o-e is for people unfamiliar with XSLT and recursive processing to easily create procedural algorithms and bypass the learning curve. Absolutely, there are valid reasons for using d-o-e, such as writing ASP.NET page directives from XSLT, but most cases for d-o-e can be solved through a deeper familiarity with XSLT processing. Oleg Tkachenko has a great post on d-o-e in the microsoft.public.dotnet.xml newsgroup that further explains the architectural reasons why d-o-e should be avoided in most cases.
Even a compulsory knowledge of XSLT and proper uses for d-o-e might throw you if you attempt to use d-o-e using System.Xml.XslTransformation. Specifically, d-o-e is ignored when using XslTransform to transform to an XmlTextWriter. This is not due to the XslTransform, but rather that it delegates the serialization semantics to the target of the transformation, the XmlTextWriter. The XmlTextWriter, in turn, serializes the result tree it receives as well-formed XML by ignoring d-o-e. The good news is that you can still use d-o-e given the warnings in paragraph 1 above by not serializing the XSLT to the XmlTextWriter, but rather another target that is not responsible for writing well-formed XML. Such a target might be the System.IO.StringWriter, or you might transform directly to a System.IO.Stream implementation.
Consider the following code examples:
System.Xml.Xsl.XslTransform trans = new System.Xml.Xsl.XslTransform();
trans.Load(Server.MapPath("xsltfile1.xslt"),new System.Xml.XmlUrlResolver());
System.Xml.XPath.XPathDocument doc = new System.Xml.XPath.XPathDocument(Server.MapPath("xmlfile1.xml"));
System.IO.StringWriter swriter = new System.IO.StringWriter();
trans.Transform(doc,null,swriter,new System.Xml.XmlUrlResolver());
System.Diagnostics.Debug.WriteLine("===Using StringWriter===");
System.Diagnostics.Debug.WriteLine(swriter.ToString());
System.Diagnostics.Debug.WriteLine(string.Empty);
System.Diagnostics.Debug.WriteLine("===Using XmlTextWriter===");
swriter = new System.IO.StringWriter();
System.Xml.XmlTextWriter xwriter = new System.Xml.XmlTextWriter(swriter);
trans.Transform(doc,null,xwriter,new System.Xml.XmlUrlResolver());
xwriter.Flush();
System.Diagnostics.Debug.WriteLine(swriter.ToString());
Using a simple XML file as the source (XslTransform needs a well-formed XML document for its input):
<?
xml version="1.0" encoding="utf-8" ?>
<
root/>
And a simple XSLT transformation:
<?
xml version="1.0"?>
<
xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:template match="/">
<root>
<xsl:text disable-output-escaping="yes"><![CDATA[<table/>]]></xsl:text>
<xsl:text disable-output-escaping="yes"><table/></xsl:text>
<xsl:value-of disable-output-escaping="yes" select="'<table/>'" />
</root>
</xsl:template>
</
xsl:stylesheet>
The output you will see in the Output window is:
===Using StringWriter===
<?xml version="1.0" encoding="utf-16"?><root><table/><table/><table/></root>
===Using XmlTextWriter===
<root><table/><table/><table/></root>