MultiXmlTextWriter 多XML输出

// MultiOutTransfrom.cs
namespace MultiOutput.Test {
    
using System;
    
using System.Xml.XPath;
    
using System.Xml.Xsl;
    
using System.Xml;
    
using System.Text;
    
using System.IO;
    
using MultiOutput;    
    
    
/// <summary>
    
/// <c>MultiXmlTextWriter</c> test class.
    
/// </summary>
    
/// <remarks>Usage:<br/>
    
/// <code>MultiOutTransfrom.exe source stylesheet result</code>
    
/// </remarks>
    public class MultiOutTransform {
        
static void Main(string[] args) {            
            
try {
                XPathDocument doc 
= new XPathDocument(args[0]);
                XslTransform xslt 
= new XslTransform();
                xslt.Load(args[
1]);                
                MultiXmlTextWriter multiWriter 
= 
                    
new MultiXmlTextWriter(args[2], Encoding.UTF8);
                multiWriter.Formatting 
= Formatting.Indented;                
                xslt.Transform(doc, 
null, multiWriter);                
            } 
catch (Exception e) {
                Console.Error.WriteLine(
"Transformation failed, an error has occured:");
                Console.Error.WriteLine(e);
            }
        }
    }
}
// MultiXmlTextWriter.cs
namespace MultiOutput {
    
using System;
    
using System.Xml;
    
using System.Text;
    
using System.Collections;    
    
using System.IO;
    
using System.Security;
    
    
/// <summary>
    
/// Specifies the redirecting state of the <c>MultiXmlTextWriter</c>.
    
/// </summary>
    internal enum RedirectState {
        
/// <summary>
        
/// The output is being relayed further (default).
        
/// </summary>
        Relaying,
        
/// <summary>
        
/// The output is being redirected.
        
/// </summary>
        Redirecting,
        
/// <summary>
        
/// <c>&lt;exsl:document></c> attributes are being written
        
/// </summary>            
        WritingRedirectElementAttrs,
        
/// <summary>
        
/// <c>&lt;exsl:document></c> attribute value is being written
        
/// </summary>
        WritingRedirectElementAttrValue
    }
    
    
/// <summary>
    
/// <para><c>MultiXmlTextWriter</c> class extends standard <c>XmlTextWriter</c> class 
    
/// and represents an XML writer that provides a fast, 
    
/// non-cached, forward-only way of generating multiple output files containing
    
/// either text data or XML data that conforms to the W3C Extensible Markup 
    
/// Language (XML) 1.0 and the Namespaces in XML recommendations.</para>    
    
/// </summary>
    
/// <remarks>
    
/// <para>Instances of <c>MultiXmlTextWriter</c> class regognize special element 
    
/// (<c>&lt;exsl:document></c> in <c>"http://exslt.org/common"</c> namespace) as
    
/// instruction to redirect the output of this element's content to another file. 
    
/// When using with <c>XslTransform</c> class, <c>MultiXmlTextWriter</c> class 
    
/// allows to generate multiple XSL Transfromation results.</para>    
    
/// <para><c>MultiXmlTextWriter</c> class extends <c>System.Xml.XmlTextWriter</c>
    
/// class, therefore its instances can be passed directly to the overloaded 
    
/// <c>XslTransform.Transform()</c> method, which accepts <c>XmlWriter</c> as 
    
/// object to write the transformation result to. All actual XML writing work 
    
/// <c>MultiXmlTextWriter</c> class delegates to its base class, but it overrides 
    
/// several <c>XmlTextWriter</c> class methods to implement output switching logic 
    
/// as follows: once <c>&lt;exsl:document></c> element start tag is detected in 
    
/// the XML stream, new writer (<c>XmlTextWriter</c> or <c>StreamWriter</c> depending on
    
/// <c>method</c> attribute value) object is created with parameters as specified 
    
/// in the attributes of the <c>&lt;exsl:document></c> element and the output 
    
/// is switched to this newly created writer untill the end tag of the 
    
/// <c>&lt;exsl:document></c> element is encountered.</para>
    
/// <para><c>&lt;exsl:document></c> element syntax is as follows:
    
/// <code>
    
/// &lt;exsl:document
    
///    href = { uri-reference }
    
///    method = { "xml" | "text" }
    
///    encoding = { string }
    
///    standalone = { "yes" | "no" }
    
///    doctype-public = { string }
    
///    doctype-system = { string }
    
///    indent = { "yes" | "no" }
    
///    &lt;-- Content: template -->
    
/// &lt;/exsl:document>
    
/// </code></para>
    
/// <para>
    
/// The <c>href</c> attribute specifies where new result document should be stored, 
    
/// it must be an absolute or relative URI. Relative URIs are resolved 
    
/// relatively to the parent result document base URI. If the <c>href</c> attribute
    
/// specifies that the output should be redirected to a file in a directory
    
/// and that directory does not exist, it will be created. This allows to create 
    
/// directory trees of any complexity.</para>
    
/// <para>Semantics of the rest attributes is as defined in W3C XSLT 1.0 Recommendation 
    
/// for <c>&lt;xsl:output></c> element, see 
    
/// <a href="http://www.w3.org/TR/xslt.html#output">http://www.w3.org/TR/xslt.html#output</a>.
    
/// </para>
    
/// <para><b>Note:</b> <c>&lt;exsl:document></c> element namespace prefix must be bound to 
    
/// <c>"http://exslt.org/common"</c> namespace URI in order to be recognized by 
    
/// <c>MultiXmlTextWriter</c> class as a redirecting instruction. </para>
    
/// </remarks>
    
/// <example>This example shows how to use <c>MultiXmlTextWriter</c> along with 
    
/// <c>XslTransform</c> to achieve create multiple result documents in one
    
/// transfromation run:
    
/// <para>In XSL stylesheet document declare <c>"http://exslt.org/common"</c> namespace
    
/// and whenever you want to create new result document make use of <c>&lt;exsl:documnet></c>
    
/// element:<br/>
    
/// <c>style.xsl</c> stylesheet fragment:
    
/// <code>
    
/// <![CDATA[
    /// <xsl:stylesheet version="1.0" 
    ///   xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
    
///   ]]><b>xmlns:exsl= "http://exslt.org/common"</b><![CDATA[ 
    ///   ]]><b>exclude-result-prefixes="exsl"</b>><![CDATA[ 
    ///   <xsl:template match="book">
    
///     <!-- Builds frameset -->
    
///     <html> 
    
///       <head>
    
///         <title><xsl:value-of select="@title"/></title> 
    
///       </head>
    
///       <frameset cols="20%,80%"> 
    
///         <frame src="toc.html"/> 
    
///         <!-- Builds table of contents output document -->    
    
///         ]]><b>&lt;exsl:document href="toc.html" indent="yes"></b><![CDATA[
    ///           <html>
    
///             <head>
    
///               <title>Table of Contents</title>
    
///             </head>
    
///             <body>
    
///               <ul>
    
///                 <xsl:apply-templates mode="toc"/> 
    
///               </ul> 
    
///             </body>                      
    
///           </html>
    
///         ]]><b>&lt;/exsl:document></b><![CDATA[ 
    ///         <frame src="{chapter[1]/@id}.html" name="body" />
    
///         <xsl:apply-templates />
    
///       </frameset> 
    
///     </html>
    
///       
    
///
    
/// ]]>
    
/// </code>
    
/// C# code fragment:    
    
/// <code>
    
/// XPathDocument doc = new XPathDocument("book.xml");
    
/// XslTransform xslt = new XslTransform();
    
/// xslt.Load("style.xsl");                
    
/// MultiXmlTextWriter multiWriter = 
    
///     new MultiXmlTextWriter("index.html", Encoding.UTF8);
    
/// multiWriter.Formatting = Formatting.Indented;
    
/// xslt.Transform(doc, null, multiWriter);
    
/// </code>
    
/// </para>
    
/// </example>
    public class MultiXmlTextWriter : XmlTextWriter {
        
/// <summary>
        
/// This constant is the namespace <c>&lt;exsl:document></c> element 
        
/// should belong to in order to be recognized as redirect instruction.
        
/// It's <c>"http://exslt.org/common"</c> as defined by 
        
/// <a href="http://www.exslt.org">EXSLT community initiative</a>.
        
/// </summary>                 
        protected const string RedirectNamespace = "http://exslt.org/common";        
        
/// <summary>
        
/// This constant is the redirect instruction element name.
        
/// It's <c>"document"</c> as defined by 
        
/// <a href="http://www.exslt.org">EXSLT community initiative</a>.
        
/// </summary>
        protected const string RedirectElementName = "document";        
                
        
// Stack of output states
        Stack states = null;        
        
// Current output state
        OutputState state = null;                        
        
// Currently processed attribute name 
        string currentAttributeName;       
                                
        
//Redirecting state - relaying by default
        RedirectState redirectState = RedirectState.Relaying;
                                                       
        
/// <summary>
        
/// Creates an instance of the <c>MultiXmlTextWriter</c> class using the specified filename and
        
/// encoding.
        
/// Inherited from <c>XmlTextWriter</c>, see <see cref="XmlTextWriter"/>.
        
/// Overridden to set output directory.
        
/// </summary>
        
/// <param name="fileName">The filename to write to. If the file exists, it will truncate it and overwrite it 
        
/// with the new content.</param>
        
/// <param name="encoding">The encoding to generate. If encoding is a null reference it writes the file out 
        
/// as UTF-8, and omits the encoding attribute from the ProcessingInstruction.</param>
        
/// <exception cref="ArgumentException">The encoding is not supported; the filename is empty, contains only 
        
/// white space, or contains one or more invalid characters.</exception>
        
/// <exception cref="UnauthorizedAccessException">Access is denied.</exception>
        
/// <exception cref="ArgumentNullException">The filename is a null reference.</exception>
        
/// <exception cref="DirectoryNotFoundException">The directory to write to is not found.</exception>
        
/// <exception cref="IOException">The filename includes an incorrect or invalid syntax 
        
/// for file name, directory name, or volume label syntax.</exception>
        
/// <exception cref="SecurityException">The caller does not have the required permission.</exception>
        public MultiXmlTextWriter(String fileName, Encoding encoding):base(fileName, encoding) {
            DirectoryInfo dir 
= Directory.GetParent(fileName);                       
            Directory.SetCurrentDirectory(dir.ToString());
        }
        
        
/// <summary>
        
/// Creates an instance of the <c>MultiXmlTextWriter</c> class using the specified 
        
/// <c>TextWriter</c>, see <see cref="TextWriter"/>.
        
/// Inherited from <c>XmlTextWriter</c>, see <see cref="XmlTextWriter"/>.
        
/// </summary>
        
/// <param name="w">The <c>TextWriter</c> to write to. It is assumed that the <c>TextWriter</c> is 
        
/// already set to the correct encoding.</param>
        public MultiXmlTextWriter(TextWriter w):base(w) {}
        
        
/// <summary>
        
/// Creates an instance of the <c>MultiXmlTextWriter</c> class using the specified 
        
/// stream and encoding.
        
/// Inherited from <c>XmlTextWriter</c>, see <see cref="XmlTextWriter"/>.
        
/// </summary>
        
/// <param name="w">The stream to which you want to write.</param>
        
/// <param name="encoding">The encoding to generate. If encoding is a null 
        
/// reference it writes out the stream as UTF-8 and omits the encoding attribute 
        
/// from the ProcessingInstruction.</param>
        
/// <exception cref="ArgumentException">The encoding is not supported or the stream 
        
/// cannot be written to.</exception>
        
/// <exception cref="ArgumentNullException">w is a null reference.</exception>
        public MultiXmlTextWriter(Stream w, Encoding encoding):base(w, encoding) {}
                        
        
/// <summary>
        
/// Checks possible start of <c>&lt;exsl:document></c> element content.         
        
/// </summary>
        
/// <remarks>
        
/// When <c>&lt;exsl:document></c> element start tag is detected, the beginning of the 
        
/// element's content might be detected as any next character data (not attribute
        
/// value though), element start tag, processing instruction or comment.
        
/// </remarks>
        
/// <exception cref="ArgumentNullException">Thrown when <c>href</c> attribute is absent.</exception>
        
/// <exception cref="ArgumentException">Thrown when a document, specified by <c>href</c> attribute is
        
/// opened alreary. Two nested <c>&lt;exsl:document></c></exception> elements cannot specify the same 
        
/// output URI in their <c>href</c> attributes.
        private void CheckContentStart() {
            
if (redirectState == RedirectState.WritingRedirectElementAttrs) {
                
//Check required href attribute
                if (state.Href == null)
                    
throw new ArgumentNullException("'href' attribute of exsl:document element must be specified.");            
                
//Are we writing to this URI already?
                foreach (OutputState nestedState in states)
                    
if (nestedState.Href == state.Href)
                        
throw new ArgumentException("Cannot write to " + state.Href + " two documents simultaneously.");                
                state.InitWriter();                                
                redirectState 
= RedirectState.Redirecting;
            }    
        } 
        
/// <summary>
        
/// Writes the specified start tag and associates it with the given namespace and prefix.
        
/// Inherited from <c>XmlTextWriter</c>, see <see cref="XmlTextWriter.WriteStartElement"/>
        
/// Overridden to detect <c>exsl:document</c> element start tag.
        
/// </summary>        
        
/// <param name="prefix">The namespace prefix of the element.</param>
        
/// <param name="localName">The local name of the element.</param>
        
/// <param name="ns">The namespace URI to associate with the element. If this namespace 
        
/// is already in scope and has an associated prefix then the writer will automatically write that prefix also. </param>
        
/// <exception cref="InvalidOperationException">The writer is closed.</exception>
        public override void WriteStartElement(string prefix, string localName, string ns) {        
            CheckContentStart();                            
            
//Is it exsl:document redirecting instruction?
            if (ns == RedirectNamespace && localName == RedirectElementName) {                
                
//Lazy stack of states
                if (states == null)
                    states 
= new Stack();
                
//If we are redirecting already - push the current state into the stack
                if (redirectState == RedirectState.Redirecting)
                    states.Push(state);
                
//Initialize new state
                state = new OutputState();
                redirectState 
= RedirectState.WritingRedirectElementAttrs;
            } 
else {                            
                
if (redirectState == RedirectState.Redirecting) {
                    
if (state.Method == OutputMethod.Text) {
                        state.Depth
++;
                        
return;
                    }   
                    
//Write doctype before the first element
                    if (state.Depth == 0 && state.SystemDoctype != null)
                        
if (prefix != String.Empty)
                            state.XmlWriter.WriteDocType(prefix
+":"+localName, 
                                state.PublicDoctype,state.SystemDoctype, 
null);
                        
else
                            state.XmlWriter.WriteDocType(localName, 
                                state.PublicDoctype,state.SystemDoctype, 
null);   
                    state.XmlWriter.WriteStartElement(prefix, localName, ns);                
                    state.Depth
++;
                } 
else
                    
base.WriteStartElement(prefix, localName, ns);              
            }
        }
        
        
/// <summary>
        
/// Finishes output redirecting - closes current writer 
        
/// and pops previous state.
        
/// </summary>
        internal void FinishRedirecting() {            
            state.CloseWriter();
            
//Pop previous state if it exists
            if (states.Count != 0) {
                state 
= (OutputState)states.Pop();
                redirectState 
= RedirectState.Redirecting;
            } 
else {
                state 
= null;
                redirectState 
= RedirectState.Relaying;
            }
        }
        
        
/// <summary>
        
/// Closes one element and pops the corresponding namespace scope.
        
/// Inherited from <c>XmlTextWriter</c>, see <see cref="XmlTextWriter.WriteEndElement"/>
        
/// Overridden to detect <c>exsl:document</c> element end tag.
        
/// </summary>                
        public override void WriteEndElement() {
            CheckContentStart();
            
if (redirectState == RedirectState.Redirecting) {                
                
//Check if that's exsl:document end tag
                if (state.Depth-- == 0)
                    FinishRedirecting();    
                
else {
                    
if (state.Method == OutputMethod.Text)
                        
return;
                    state.XmlWriter.WriteEndElement();                         
                }
            } 
            
else 
                
base.WriteEndElement();
        }
        
        
/// <summary>
        
/// Closes one element and pops the corresponding namespace scope.
        
/// Inherited from <c>XmlTextWriter</c>, see <see cref="XmlTextWriter.WriteFullEndElement"/>
        
/// Overridden to detect <c>exsl:document</c> element end tag.
        
/// </summary>                
        public override void WriteFullEndElement() {
            CheckContentStart();
            
if (redirectState == RedirectState.Redirecting) {                
                
//Check if it's exsl:document end tag
                if (state.Depth-- == 0)                                        
                    FinishRedirecting();               
                
else {
                    
if (state.Method == OutputMethod.Text)
                        
return;
                    state.XmlWriter.WriteFullEndElement();                         
                }
            } 
else 
                
base.WriteFullEndElement();                
        }
                
        
/// <summary>
        
/// Writes the start of an attribute.
        
/// Inherited from <c>XmlTextWriter</c>, see <see cref="XmlTextWriter.WriteStartAttribute"/>
        
/// Overridden to detect <c>exsl:document</c> attribute names and to redirect
        
/// the output.
        
/// </summary>
        
/// <param name="prefix">Namespace prefix of the attribute.</param>
        
/// <param name="localName">Local name of the attribute.</param>
        
/// <param name="ns">Namespace URI of the attribute.</param>                                            
        
/// <exception cref="ArgumentException"><c>localName</c>c> is either a null reference or <c>String.Empty</c>.</exception>
        public override void WriteStartAttribute(string prefix, string localName, string ns) {
            
if (redirectState == RedirectState.WritingRedirectElementAttrs) {                                
                redirectState 
= RedirectState.WritingRedirectElementAttrValue;
                currentAttributeName 
= localName;                
            } 
else if (redirectState == RedirectState.Redirecting) {
                
if (state.Method == OutputMethod.Text)
                    
return;
                state.XmlWriter.WriteStartAttribute(prefix, localName, ns);                
            } 
else
                
base.WriteStartAttribute(prefix, localName, ns);
        }
                
        
/// <summary>
        
/// Closes the previous <c>WriteStartAttribute</c> call.
        
/// Inherited from <c>XmlTextWriter</c>, see <see cref="XmlTextWriter.WriteEndAttribute"/>
        
/// Overridden to redirect the output.
        
/// </summary>        
        public override void WriteEndAttribute() {                         
            
if (redirectState == RedirectState.WritingRedirectElementAttrValue)
                redirectState 
= RedirectState.WritingRedirectElementAttrs;
            
else if (redirectState == RedirectState.Redirecting) {
                
if (state.Method == OutputMethod.Text)
                    
return;
                state.XmlWriter.WriteEndAttribute();
            } 
else
                
base.WriteEndAttribute();
        }
        
        
/// <summary>
        
/// Writes out a comment &lt;!----> containing the specified text.
        
/// Inherited from <c>XmlTextWriter</c>, see <see cref="XmlTextWriter.WriteComment"/>
        
/// Overriden to redirect the output.
        
/// </summary>
        
/// <param name="text">Text to place inside the comment.</param>        
        
/// <exception cref="ArgumentException">The text would result in a non-well formed XML document.</exception>
        
/// <exception cref="InvalidOperationException">The <c>WriteState</c> is Closed.</exception>
        public override void WriteComment(string text) {            
            CheckContentStart();
            
if (redirectState == RedirectState.Redirecting) {
                
if (state.Method == OutputMethod.Text)
                    
return;
                state.XmlWriter.WriteComment(text);
            } 
else
                
base.WriteComment(text);
        }
        
        
/// <summary>
        
/// Writes out a processing instruction with a space between the name 
        
/// and text as follows: &lt;?name text?>.
        
/// Inherited from <c>XmlTextWriter</c>, see <see cref="XmlTextWriter.WriteProcessingInstruction"/>
        
/// Overridden to redirect the output.
        
/// </summary>
        
/// <param name="name">Name of the processing instruction.</param>
        
/// <param name="text">Text to include in the processing instruction.</param>        
        
/// <exception cref="ArgumentException"><para>The text would result in a non-well formed XML document.</para> 
        
/// <para><c>name</c> is either a null reference or <c>String.Empty</c>.</para>
        
/// <para>This method is being used to create an XML declaration after 
        
/// <c>WriteStartDocument</c> has already been called.</para></exception>
        public override void WriteProcessingInstruction(string name, string text) {
            CheckContentStart();
            
if (redirectState == RedirectState.Redirecting) {
                
if (state.Method == OutputMethod.Text)
                    
return;
                state.XmlWriter.WriteProcessingInstruction(name, text);
            } 
else
                
base.WriteProcessingInstruction(name, text);
        }
        
        
/// <summary>
        
/// Writes the given text content.
        
/// Inherited from <c>XmlTextWriter</c>, see <see cref="XmlTextWriter.WriteString"/>
        
/// Overridden to detect <c>exsl:document</c> element attribute values and to 
        
/// redirect the output.
        
/// </summary>
        
/// <param name="text">Text to write.</param>        
        
/// <exception cref="ArgumentException">The text string contains an invalid surrogate pair.</exception>
        public override void WriteString(string text) {
            
//Possible exsl:document's attribute value
            if (redirectState == RedirectState.WritingRedirectElementAttrValue) {
                
switch (currentAttributeName) {
                    
case "href":
                        state.Href 
= text;
                        
break;
                    
case "method":
                        
if (text == "text")
                            state.Method 
= OutputMethod.Text;
                        
break;    
                    
case "encoding":
                        
try {
                            state.Encoding 
= Encoding.GetEncoding(text);
                        } 
catch (Exception) {}    
                        
break;
                    
case "indent":
                        
if (text == "yes")
                            state.Indent 
= true;
                        
break;
                    
case "doctype-public":
                        state.PublicDoctype 
= text;
                        
break;
                    
case "doctype-system":
                        state.SystemDoctype 
= text;
                        
break;    
                    
case "standalone":
                        
if (text == "yes")
                            state.Standalone 
= true;
                        
break;
                    
default:
                        
break;    
                }                
                
return;
            } 
else
                CheckContentStart();
            
if (redirectState == RedirectState.Redirecting) {
                
if (state.Method == OutputMethod.Text)
                    state.TextWriter.Write(text);
                
else
                    state.XmlWriter.WriteString(text);
            } 
else
                
base.WriteString(text);
        }
    }                       
}
// OutputState.cs
namespace MultiOutput {
    
using System;
    
using System.Xml;
    
using System.Text;
    
using System.IO;

    
/// <summary>
    
/// XSLT output method enumeration, see W3C XSLT 1.0 Recommendation at 
    
/// <a href="http://www.w3.org/TR/xslt.html#output">http://www.w3.org/TR/xslt.html#output</a>.    
    
/// </summary>
    
/// <remarks>Only <c>xml</c> and <c>text</c> methods are supported by this version of 
    
/// the <c>MultiXmlTextWriter</c>.</remarks>
    internal enum OutputMethod { Xml, Text };
    
    
/// <summary>
    
/// This class represents redirected output state and properties.
    
/// </summary>    
    internal class OutputState {            
        
private XmlTextWriter xmlWriter;                        
        
private StreamWriter textWriter;
        
private int depth;
        
private string href;                           
        
private Encoding encoding;        
        
private bool indent;        
        
private string publicDoctype;        
        
private string systemDoctype;        
        
private bool standalone;        
        
private string storedDir;
        
private OutputMethod method;
                                                                                                     
        
/// <summary>
        
/// Creates new <c>OutputState</c> with default properties values:
        
/// UTF8 encoding, no indentation, nonstandalone document, XML output
        
/// method.
        
/// </summary>                                    
        public OutputState() {
            encoding 
= System.Text.Encoding.UTF8;
            indent 
= false;
            standalone 
= false;
            method 
= OutputMethod.Xml;
        }                                   
         
        
/// <summary>
        
/// Initializes the writer to write redirected output. 
        
/// </summary>              
        
/// <remarks>Depending on the <c>method</c> attribute value, 
        
/// <c>XmlTextWriter</c> or <c>StreamWriter</c> is created. 
        
/// <c>XmlTextWriter</c> is used for outputting XML and  
        
/// <c>StreamWriter</c> - for plain text.
        
/// </remarks>
        public void InitWriter() {
            
// Save current directory
            storedDir = Directory.GetCurrentDirectory();
            DirectoryInfo dir 
= Directory.GetParent(href);
            
if (!dir.Exists)
                dir.Create();
            
// Create writer
            if (method == OutputMethod.Xml) {
                xmlWriter 
= new XmlTextWriter(href, encoding);
                
if (indent)
                    xmlWriter.Formatting 
= Formatting.Indented;
                
if (standalone)    
                    xmlWriter.WriteStartDocument(
true);
                
else
                    xmlWriter.WriteStartDocument();
            } 
else
                textWriter 
= new StreamWriter(href, false, encoding);
            
// Set new current directory            
            Directory.SetCurrentDirectory(dir.ToString());                                    
        }      
        
        
/// <summary>
        
/// Closes the writer that was used to write redirected output.
        
/// </summary>
        public void CloseWriter() {
            
if (method == OutputMethod.Xml) {
                xmlWriter.WriteEndDocument();
                xmlWriter.Close();    
            } 
else
                textWriter.Close();
            
// Restore previous current directory
            Directory.SetCurrentDirectory(storedDir);
        }
                                                   
        
/// <summary>
        
/// Specifies whether the result document should be written with 
        
/// a standalone XML document declaration.
        
/// </summary>
        
/// <value>Standalone XML declaration as per W3C XSLT 1.0 Recommendation (see 
        
/// <a href="http://www.w3.org/TR/xslt.html#output">http://www.w3.org/TR/xslt.html#output</a>
        
/// for more info).</value>
        
/// <remarks>The property does not affect output while output method is <c>text</c>.</remarks>            
        public bool Standalone {
            
get { return standalone; }
            
set { standalone = value; }
        }        
        
        
/// <summary>
        
/// Specifies output method.
        
/// </summary>
        
/// <value>Output Method as per W3C XSLT 1.0 Recommendation (see 
        
/// <a href="http://www.w3.org/TR/xslt.html#output">http://www.w3.org/TR/xslt.html#output</a>
        
/// for more info).</value>        
        public OutputMethod Method {
            
get { return method; }
            
set { method = value; }
        }
        
        
/// <summary>
        
/// Specifies the URI where the result document should be written to.
        
/// </summary>                            
        
/// <value>Absolute or relative URI of the output document.</value>
        public string Href {
            
get { return href; }
            
set { href = value; }
        }
        
        
/// <summary>
        
/// Specifies the preferred character encoding of the result document.
        
/// </summary>
        
/// <value>Output encoding as per W3C XSLT 1.0 Recommendation (see 
        
/// <a href="http://www.w3.org/TR/xslt.html#output">http://www.w3.org/TR/xslt.html#output</a>
        
/// for more info).</value>
        public Encoding Encoding {
            
get { return encoding; }
            
set { encoding = value; }
        }
        
        
/// <summary>
        
/// Specifies whether the result document should be written in the 
        
/// indented form.
        
/// </summary>
        
/// <value>Output document formatting as per W3C XSLT 1.0 Recommendation (see 
        
/// <a href="http://www.w3.org/TR/xslt.html#output">http://www.w3.org/TR/xslt.html#output</a>
        
/// for more info).</value>
        
/// <remarks>The property does not affect output while output method is <c>text</c>.</remarks>
        public bool Indent {
            
get { return indent; }
            
set { indent = value; }
        }
        
        
/// <summary>
        
/// Specifies the public identifier to be used in the document 
        
/// type declaration.
        
/// </summary>
        
/// <value>Public part of the output document type definition as per W3C XSLT 1.0 Recommendation (see 
        
/// <a href="http://www.w3.org/TR/xslt.html#output">http://www.w3.org/TR/xslt.html#output</a>
        
/// for more info).</value>
        
/// <remarks>The property does not affect output while output method is <c>text</c>.</remarks>
        public string PublicDoctype {
            
get { return publicDoctype; }
            
set { publicDoctype = value; }
        }
        
        
/// <summary>
        
/// Specifies the system identifier to be used in the document 
        
/// type declaration.
        
/// </summary>
        
/// <value>System part of the output document type definition as per W3C XSLT 1.0 Recommendation (see 
        
/// <a href="http://www.w3.org/TR/xslt.html#output">http://www.w3.org/TR/xslt.html#output</a>
        
/// for more info).</value>
        
/// <remarks>The property does not affect output while output method is <c>text</c>.</remarks>
        public string SystemDoctype {
            
get { return systemDoctype; }
            
set { systemDoctype = value; }
        }                                    
                                    
        
/// <summary>
        
/// Actual <c>XmlTextWriter</c> used to write the redirected 
        
/// result document.
        
/// </summary>              
        
/// <value><c>XmlWriter</c>, which is used to write the output document in XML method.</value>                      
        public XmlTextWriter XmlWriter {
            
get { return xmlWriter; }                                
        }
        
        
/// <summary>
        
/// Actual <c>TextWriter</c> used to write the redirected 
        
/// result document in text output method.
        
/// </summary>                                    
        
/// <value><c>StreamWriter</c>, which is used to write the output document in text method.</value>
        public StreamWriter TextWriter {
            
get { return textWriter; }                                
        }    
            
        
/// <summary>
        
/// Tree depth (used to detect end tag of the <c>exsl:document</c>).
        
/// </summary>
        
/// <value>Current output tree depth.</value>
        public int Depth {
            
get { return depth; }
            
set { depth = value; }
        }                                                 
    }
}

posted @ 2005-11-10 13:16  Rookie.Zhang  阅读(461)  评论(0)    收藏  举报