6

I'm using an XsltCompiledTransform to transform some XML into a fragment of HTML (not a complete HTML document, just a DIV that I will include in page generated elsewhere).

I'm doing the transformation as follows:

StringBuilder output = new StringBuilder();

XmlReader rawData = BusinessObject.GetXml();
XmlWriter transformedData = XmlWriter.Create(output);

XslCompiledTransform transform = new XslCompiledTransform();

transform.Load("stylesheet.xslt");

transform.Transform(rawData, transformedData);

Response.Write(output.ToString());

My problem is that the result of the transform always begins with this XML directive:

<?xml version="1.0" encoding="utf-16"?>

How do I prevent this from appearing in my transformed data?

EDIT:

I'm telling the XSLT that I don't want it to output an xml declaration with

<xsl:output method="html" version="4.0" omit-xml-declaration="yes"/>

but this seems to have no effect on the directive appearing in my output.

Interestingly, both my XML data source and my XSLT transform specify themselves as UTF-8 not UTF-16.

UPDATE: The UTF-16 seems to be appearing because I'm using a string(builder) as an output mechanism. When I change the code to use a MemoryStream instead of a StringBuilder, my UTF-8 encoding is preserved. I'm guessing this has something to do with the internal workings of the string type and how it deals with encoding.

kristian
  • 22,731
  • 8
  • 50
  • 78

2 Answers2

14

You need to use an XmlWriterSettings object. Set its properties to omit the XML declaration, and pass it to the constructor of your XmlWriter.

StringBuilder output = new StringBuilder();
XmlReader rawData = BusinessObject.GetXml();

XmlWriterSettings writerSettings = new XmlWriterSettings();
writerSettings.OmitXmlDeclaration = true;

using (XmlWriter transformedData = XmlWriter.Create(output, writerSettings))
{
  XslCompiledTransform transform = new XslCompiledTransform();
  transform.Load("stylesheet.xslt");
  transform.Transform(data, transformedData);
  Response.Write(output.ToString());
}
kristian
  • 22,731
  • 8
  • 50
  • 78
  • Yep, that's the way to go. It's not an XSLT problem - the declaration is written by `XmlWriter` in the first place, not by `XslCompiledTransform`. – Pavel Minaev Nov 16 '09 at 23:29
  • But why doesn't the XmlWriter take its settings from the XSLT? – kristian Nov 16 '09 at 23:54
  • 1
    Because once it's created, it cannot change its settings by design. So once XSLT receives it, it cannot really do anything about it. If you use a `Transform()` overload which takes a `TextWriter` or `Stream`, it will create an `XmlWriter` with correct settings for you. – Pavel Minaev Nov 17 '09 at 00:02
  • Interesting. Thanks for the insight Pavel. – kristian Nov 17 '09 at 00:27
  • Hmm, I used the overload to output directly to memory stream, and still ran into UTF16 encoding. Perhaps its creating a default xml writer to support the stream overload anyway? Rather than worry about it, I just used the code above and all is well :) – stead Mar 06 '14 at 15:18
3

The easiest way would be to add this node to your XSLT:

<xsl:output 
    method="html" 
    omit-xml-declaration="yes"/>
Andrew Hare
  • 344,730
  • 71
  • 640
  • 635