If you would like to generate the DOCTYPE specification in the html output when using xslt transformation, you can not write the code as following:
<?
xml version="1.0" encoding="utf-8"
?>
<
xsl:stylesheet
version
="1.0"
xmlns:xsl
="http://www.w3.org/1999/XSL/Transform"
>
<
xsl:template
match
="/"
>
<!
DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"
>
<
html
>
<
body
>
</
body
>
</
html
>
</
xsl:template
>
</
xsl:stylesheet
>
It is because we can not write the DOCTYPE element in the xslt file, it's not a well-formed xml element. To achieve this goal you must use
xsl:output, just as below
<?
xml version="1.0" encoding="utf-8"
?>
<
xsl:stylesheet
version
="1.0"
xmlns:xsl
="http://www.w3.org/1999/XSL/Transform"
>
<
xsl:output
method
="html"
encoding
="utf-8"
doctype-public
="-//W3C//DTD XHTML 1.0 Transitional//EN"
doctype-system
="http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"
/>
<
xsl:template
match
="/"
>
<
html
xmlns
="http://www.w3.org/1999/xhtml"
>
<
head
>
<
title
>
<
/
title
>
</
head
>
<
body
>
</
body
>
</
html
>
</
xsl:template
>
</
xsl:stylesheet
>
The result is something like:
<!
DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"
>
<
html
xmlns
="http://www.w3.org/1999/xhtml"
>
<
head
>
<
title
></
title
>
</
head
>
<
body
>
</
body
>
</
html
>
in the
xsl:output element:
method: identifies the method that should be used for outputting the result, it can be one of xml, html or text.
encoding: specifies the preferred character encoding that the XSLT processor should use to encode sequences of characters as sequences of bytes
doctype-public: specifies the public identifier to be used in the document type declaration. If given this attribute it will generate a DOCTYPE in the output document, such as
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN">
doctype-system: specifies the system identifier to be used in the document type declaration. If given this attribute it will generate a DOCTYPE in the output document, such as
<!DOCTYPE html SYSTEM "./dtds/book.dtd">
If both the
doctype-public and
doctype-system attributes are specified in the
xsl:output element, for example,
<xsl:output method="html" doctype-public="-//W3C//DTD XHTML 1.0 Transitional//EN" doctype-system="http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd" /> will generate the DOCTYPE like:
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">. In this situation the
doctype-system only identifies the resource(DTD) referenced.
cdata-section-elements: specifies a list of the names of elements whose text node children should be output using CDATA sections, for example, cdata-section-elements="script" will result in all the text in the elements
<script></script> are treated just as they are in
<![CDATA[]]> by the XSLT processor.
The c# code handling the transformation is below:
using
System;
using
System.Xml;
using
System.Xml.Xsl;
using
System.Xml.XPath;
using
System.Text;
using
System.IO;
this
.Response.ContentType
=
"
text/html
"
;
//
retrieve the xml document object from the model
XmlDocument doc
=
BoxImpl.BoxXml(
this
._templateId,
this
._type,
this
._boxId,
this
._op);
//
in .NET framework 2.0, it is recommended that use the XslCompiledTransform instead of XslTransform
XslCompiledTransform transform
=
new
XslCompiledTransform();
transform.Load(
this
.Server.MapPath(
"
cc.xsl
"
));
MemoryStream stream
=
new
MemoryStream();
transform.Transform(doc.CreateNavigator(),
null
, stream);
//
maybe the Position was moved to the end of the MemoryStream while transforming,
//
so it's necessary to set this attribute to 0 before reading the stream
stream.Position
=
0
;
//
the encoding attribute specified in the xsl:output node is utf-8,
//
so here we read the output stream using the System.Text.Encoding.UTF8 correspondingly
StreamReader reader
=
new
StreamReader(stream, System.Text.Encoding.UTF8);
this
.Response.Write(reader.ReadToEnd());
reader.Close();
stream.Close();