XslCompiledTransform Problems

I ran into a real stumper this morning, which the Google helped me fix. Here’s the code in question:

HttpWebRequest request = (HttpWebRequest)WebRequest.Create(uri);
// request.Credentials = new NetworkCredential(user, password);
HttpWebResponse response = (HttpWebResponse)request.GetResponse();
string xslpath = Server.MapPath("/path/xsl/mytransform.xslt");
XPathDocument xml = new XPathDocument(response.GetResponseStream());
XslCompiledTransform trans = new XslCompiledTransform();
trans.Load(xslpath);
StringBuilder sb = new StringBuilder();
StringWriter sw = new StringWriter(sb);
XmlTextWriter writer = new XmlTextWriter(sw);
trans.Transform(xml,null,writer);
this.OutputDiv.InnerHtml = sb.ToString();

This was causing my <div> tags to incorrectly nest themselves in odd ways – a cascade of Russian dolls.

I saw some search results that suggested it was a problem with XslCompiledTransform, and lo and behold when I moved back to the now-deprecated XslTransform class, and turned warnings off, it worked.

Hmm, says I: that can’t be the preferred solution, can it?

The answer is in the third-to-last line above: if you use the XhtmlTextWriter instead of the XmlTextWriter, things work as expected. I have no idea why yet.

XhtmlTextWriter writer = new XhtmlTextWriter(sw);

Advertisements

4 Responses to “XslCompiledTransform Problems”


  1. 1 gavin February 15, 2008 at 11:24 am

    Without looking at it, my guess is that using XhtmlTextWriter prevents the early-close problem, where an empty div, for example, is rendered as instead of . Both are valid XML, and — in theory — valid XHTML. In reality, though, certain tags (such as div, script, and sometimes td) confuse browsers, which regard them as open tags, and interpret the next available closing tag (which of course belongs to another element) as its closing tag, resulting in the nesting problems you mentioned. Presumably, the XhtmlTextWriter is aware of all this, and renders accordingly.

    Anyway, it’s a good tip — so far I have handled this by inserting empty comment elements (to prevent an empty parent) where this might be a problem.

  2. 2 balaji August 26, 2008 at 7:30 pm

    Could you post the code of XhtmlWriter? Thanks

  3. 3 Anthony Stevens August 26, 2008 at 7:59 pm

    @balaji: The XHtmlTextWriter is a .NET class, not my own creation.

  4. 4 Bryan September 4, 2008 at 10:30 am

    I am having problems as well. Here is the code that highlights the issue:

    #pragma warning disable // because we are using depricated objects
    static void Main(string[] args)
    {
    /*
    * There are two problems:
    * 1. The characters (CRLF) are not being output by the new object.
    * 2. Anything not in xml tags causes a crlf to be inserted.
    */

    // xsl file
    string xsltFile = @”


    This text causes the crlf to be applied in the new object.
    This text has no crlf as behaves as expected.

    “;

    // input test file
    string inputFileAsci =
    @”
    This is test 1
    This is test 2
    This is test 3
    This is test 4
    This is test 5
    “;

    System.Text.ASCIIEncoding encoding = new System.Text.ASCIIEncoding();
    byte[] input = encoding.GetBytes(inputFileAsci);

    // old object
    System.Xml.Xsl.XslTransform transform1 = new System.Xml.Xsl.XslTransform();
    transform1.Load(new XmlTextReader(new StringReader(xsltFile)), new XmlUrlResolver());
    MemoryStream ms1 = new MemoryStream(input, 0, input.Length);
    XPathDocument doc1 = new XPathDocument(ms1);
    MemoryStream output1 = new MemoryStream();
    transform1.Transform(doc1, null, output1);
    Console.WriteLine(“GOOD – Original XslTransform Object”);
    Console.Write(encoding.GetString(output1.ToArray()));

    Console.WriteLine();

    // new object
    XslCompiledTransform transform2 = new System.Xml.Xsl.XslCompiledTransform();
    XsltSettings settings = new XsltSettings(true, true);
    transform2.Load(new XmlTextReader(new StringReader(xsltFile)), settings, new XmlUrlResolver());
    MemoryStream ms2 = new MemoryStream(input, 0, input.Length);
    XmlTextReader doc2 = new XmlTextReader(ms2);
    MemoryStream output2 = new MemoryStream();
    transform2.Transform(doc2, null, output2);
    Console.WriteLine(“BAD – New XslComiledTransform Object”);
    Console.WriteLine(encoding.GetString(output2.ToArray()));

    Console.Read();

    }


Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s





%d bloggers like this: