DocumentXmlWriter.cs source code in C# .NET

Source code for the .NET framework in C#

                        

Code:

/ 4.0 / 4.0 / DEVDIV_TFS / Dev10 / Releases / RTMRel / ndp / fx / src / Xml / System / Xml / Dom / DocumentXmlWriter.cs / 1305376 / DocumentXmlWriter.cs

                            //------------------------------------------------------------------------------ 
// 
//     Copyright (c) Microsoft Corporation.  All rights reserved.
// 
// [....] 
//-----------------------------------------------------------------------------
 
using System; 
using System.Collections;
using System.Collections.Generic; 
using System.Diagnostics;
using System.Xml.Schema;

namespace System.Xml { 
    enum DocumentXmlWriterType {
        InsertSiblingAfter, 
        InsertSiblingBefore, 
        PrependChild,
        AppendChild, 
        AppendAttribute,
        ReplaceToFollowingSibling,
    }
 
    // Implements a XmlWriter that augments a XmlDocument.
    sealed class DocumentXmlWriter : XmlRawWriter, IXmlNamespaceResolver { 
        enum State { 
            Error,
            Attribute, 
            Prolog,
            Fragment,
            Content,
 
            Last, // always last
        } 
 
        enum Method {
            WriteXmlDeclaration, 
            WriteStartDocument,
            WriteEndDocument,
            WriteDocType,
            WriteStartElement, 
            WriteEndElement,
            WriteFullEndElement, 
            WriteStartAttribute, 
            WriteEndAttribute,
            WriteStartNamespaceDeclaration, 
            WriteEndNamespaceDeclaration,
            WriteCData,
            WriteComment,
            WriteProcessingInstruction, 
            WriteEntityRef,
            WriteWhitespace, 
            WriteString, 
        }
 
        DocumentXmlWriterType type; // writer type
        XmlNode start; // context node
        XmlDocument document; // context document
        XmlNamespaceManager namespaceManager; // context namespace manager 
        State state; // current state
        XmlNode write; // current node 
        List fragment; // top level node cache 
        XmlWriterSettings settings; // wrapping writer settings
        DocumentXPathNavigator navigator; // context for replace 
        XmlNode end; // context for replace

        public DocumentXmlWriter(DocumentXmlWriterType type, XmlNode start, XmlDocument document) {
            this.type = type; 
            this.start = start;
            this.document = document; 
 
            state = StartState();
            fragment = new List(); 
            settings = new XmlWriterSettings();
            settings.ReadOnly = false;
            settings.CheckCharacters = false;
            settings.CloseOutput = false; 
            settings.ConformanceLevel = (state == State.Prolog ? ConformanceLevel.Document : ConformanceLevel.Fragment);
            settings.ReadOnly = true; 
        } 

        public XmlNamespaceManager NamespaceManager { 
            set {
                namespaceManager = value;
            }
        } 

        public override XmlWriterSettings Settings { 
            get { 
                return settings;
            } 
        }

        internal void SetSettings(XmlWriterSettings value) {
            settings = value; 
        }
 
        public DocumentXPathNavigator Navigator { 
            set {
                navigator = value; 
            }
        }

        public XmlNode EndNode { 
            set {
                end = value; 
            } 
        }
 
        internal override void WriteXmlDeclaration(XmlStandalone standalone) {
            VerifyState(Method.WriteXmlDeclaration);
            if (standalone != XmlStandalone.Omit) {
                XmlNode node = document.CreateXmlDeclaration("1.0", string.Empty, standalone == XmlStandalone.Yes ? "yes" : "no"); 
                AddChild(node, write);
            } 
        } 

        internal override void WriteXmlDeclaration(string xmldecl) { 
            VerifyState(Method.WriteXmlDeclaration);
            string version, encoding, standalone;
            XmlLoader.ParseXmlDeclarationValue(xmldecl, out version, out encoding, out standalone);
            XmlNode node = document.CreateXmlDeclaration(version, encoding, standalone); 
            AddChild(node, write);
        } 
 
        public override void WriteStartDocument() {
            VerifyState(Method.WriteStartDocument); 
        }

        public override void WriteStartDocument(bool standalone) {
            VerifyState(Method.WriteStartDocument); 
        }
 
        public override void WriteEndDocument() { 
            VerifyState(Method.WriteEndDocument);
        } 

        public override void WriteDocType(string name, string pubid, string sysid, string subset) {
            VerifyState(Method.WriteDocType);
            XmlNode node = document.CreateDocumentType(name, pubid, sysid, subset); 
            AddChild(node, write);
        } 
 
        public override void WriteStartElement(string prefix, string localName, string ns) {
            VerifyState(Method.WriteStartElement); 
            XmlNode node = document.CreateElement(prefix, localName, ns);
            AddChild(node, write);
            write = node;
        } 

        public override void WriteEndElement() { 
            VerifyState(Method.WriteEndElement); 
            if (write == null) {
                throw new InvalidOperationException(); 
            }
            write = write.ParentNode;
        }
 
        internal override void WriteEndElement(string prefix, string localName, string ns) {
            WriteEndElement(); 
        } 

        public override void WriteFullEndElement() { 
            VerifyState(Method.WriteFullEndElement);
            XmlElement elem = write as XmlElement;
            if (elem == null) {
                throw new InvalidOperationException(); 
            }
            elem.IsEmpty = false; 
            write = elem.ParentNode; 
        }
 
        internal override void WriteFullEndElement(string prefix, string localName, string ns) {
            WriteFullEndElement();
        }
 
        internal override void StartElementContent() {
            // nop 
        } 

        public override void WriteStartAttribute(string prefix, string localName, string ns) { 
            VerifyState(Method.WriteStartAttribute);
            XmlAttribute attr = document.CreateAttribute(prefix, localName, ns);
            AddAttribute(attr, write);
            write = attr; 
        }
 
        public override void WriteEndAttribute() { 
            VerifyState(Method.WriteEndAttribute);
            XmlAttribute attr = write as XmlAttribute; 
            if (attr == null) {
                throw new InvalidOperationException();
            }
            if (!attr.HasChildNodes) { 
                XmlNode node = document.CreateTextNode(string.Empty);
                AddChild(node, attr); 
            } 
            write = attr.OwnerElement;
        } 

        internal override void WriteNamespaceDeclaration(string prefix, string ns) {
            this.WriteStartNamespaceDeclaration(prefix);
            this.WriteString(ns); 
            this.WriteEndNamespaceDeclaration();
        } 
 
        internal override bool SupportsNamespaceDeclarationInChunks {
            get { 
                return true;
            }
        }
 
        internal override void WriteStartNamespaceDeclaration(string prefix) {
            VerifyState(Method.WriteStartNamespaceDeclaration); 
            XmlAttribute attr; 
            if (prefix.Length == 0) {
                attr = document.CreateAttribute(prefix, document.strXmlns, document.strReservedXmlns); 
            }
            else {
                attr = document.CreateAttribute(document.strXmlns, prefix, document.strReservedXmlns);
            } 
            AddAttribute(attr, write);
            write = attr; 
        } 

        internal override void WriteEndNamespaceDeclaration() { 
            VerifyState(Method.WriteEndNamespaceDeclaration);
            XmlAttribute attr = write as XmlAttribute;
            if (attr == null) {
                throw new InvalidOperationException(); 
            }
            if (!attr.HasChildNodes) { 
                XmlNode node = document.CreateTextNode(string.Empty); 
                AddChild(node, attr);
            } 
            write = attr.OwnerElement;
        }

        public override void WriteCData(string text) { 
            VerifyState(Method.WriteCData);
            XmlConvert.VerifyCharData(text, ExceptionType.ArgumentException); 
            XmlNode node = document.CreateCDataSection(text); 
            AddChild(node, write);
        } 

        public override void WriteComment(string text) {
            VerifyState(Method.WriteComment);
            XmlConvert.VerifyCharData(text, ExceptionType.ArgumentException); 
            XmlNode node = document.CreateComment(text);
            AddChild(node, write); 
        } 

        public override void WriteProcessingInstruction(string name, string text) { 
            VerifyState(Method.WriteProcessingInstruction);
            XmlConvert.VerifyCharData(text, ExceptionType.ArgumentException);
            XmlNode node = document.CreateProcessingInstruction(name, text);
            AddChild(node, write); 
        }
 
        public override void WriteEntityRef(string name) { 
            VerifyState(Method.WriteEntityRef);
            XmlNode node = document.CreateEntityReference(name); 
            AddChild(node, write);
            //
        }
 
        public override void WriteCharEntity(char ch) {
            WriteString(new string(ch, 1)); 
        } 

        public override void WriteWhitespace(string text) { 
            VerifyState(Method.WriteWhitespace);
            XmlConvert.VerifyCharData(text, ExceptionType.ArgumentException);
            if (document.PreserveWhitespace) {
                XmlNode node = document.CreateWhitespace(text); 
                AddChild(node, write);
            } 
        } 

        public override void WriteString(string text) { 
            VerifyState(Method.WriteString);
            XmlConvert.VerifyCharData(text, ExceptionType.ArgumentException);
            XmlNode node = document.CreateTextNode(text);
            AddChild(node, write); 
        }
 
        public override void WriteSurrogateCharEntity(char lowCh, char highCh) { 
            WriteString(new string(new char[] {highCh, lowCh}));
        } 

        public override void WriteChars(char[] buffer, int index, int count) {
            WriteString(new string(buffer, index, count));
        } 

        public override void WriteRaw(char[] buffer, int index, int count) { 
            WriteString(new string(buffer, index, count)); 
        }
 
        public override void WriteRaw(string data) {
            WriteString(data);
        }
 
        public override void Close() {
            // nop 
        } 

        internal override void Close(WriteState currentState) { 
            if (currentState == WriteState.Error) {
                return;
            }
            try { 
                switch (type) {
                    case DocumentXmlWriterType.InsertSiblingAfter: 
                        XmlNode parent = start.ParentNode; 
                        if (parent == null) {
                            throw new InvalidOperationException(Res.GetString(Res.Xpn_MissingParent)); 
                        }
                        for (int i = fragment.Count - 1; i >= 0; i--) {
                            parent.InsertAfter(fragment[i], start);
                        } 
                        break;
                    case DocumentXmlWriterType.InsertSiblingBefore: 
                        parent = start.ParentNode; 
                        if (parent == null) {
                            throw new InvalidOperationException(Res.GetString(Res.Xpn_MissingParent)); 
                        }
                        for (int i = 0; i < fragment.Count; i++) {
                            parent.InsertBefore(fragment[i], start);
                        } 
                        break;
                    case DocumentXmlWriterType.PrependChild: 
                        for (int i = fragment.Count - 1; i >= 0; i--) { 
                            start.PrependChild(fragment[i]);
                        } 
                        break;
                    case DocumentXmlWriterType.AppendChild:
                        for (int i = 0; i < fragment.Count; i++) {
                            start.AppendChild(fragment[i]); 
                        }
                        break; 
                    case DocumentXmlWriterType.AppendAttribute: 
                        CloseWithAppendAttribute();
                        break; 
                    case DocumentXmlWriterType.ReplaceToFollowingSibling:
                        if (fragment.Count == 0) {
                            throw new InvalidOperationException(Res.GetString(Res.Xpn_NoContent));
                        } 
                        CloseWithReplaceToFollowingSibling();
                        break; 
                } 
            }
            finally { 
                fragment.Clear();
            }
        }
 
        private void CloseWithAppendAttribute() {
            XmlElement elem = start as XmlElement; 
            Debug.Assert(elem != null); 
            XmlAttributeCollection attrs = elem.Attributes;
            for (int i = 0; i < fragment.Count; i++) { 
                XmlAttribute attr = fragment[i] as XmlAttribute;
                Debug.Assert(attr != null);
                int offset = attrs.FindNodeOffsetNS(attr);
                if (offset != -1 
                    && ((XmlAttribute)attrs.Nodes[offset]).Specified) {
                    throw new XmlException(Res.Xml_DupAttributeName, attr.Prefix.Length == 0 ? attr.LocalName : string.Concat(attr.Prefix, ":", attr.LocalName)); 
                } 
            }
            for (int i = 0; i < fragment.Count; i++) { 
                XmlAttribute attr = fragment[i] as XmlAttribute;
                Debug.Assert(attr != null);
                attrs.Append(attr);
            } 
        }
 
        private void CloseWithReplaceToFollowingSibling() { 
            XmlNode parent = start.ParentNode;
            if (parent == null) { 
                throw new InvalidOperationException(Res.GetString(Res.Xpn_MissingParent));
            }
            if (start != end) {
                if (!DocumentXPathNavigator.IsFollowingSibling(start, end)) { 
                    throw new InvalidOperationException(Res.GetString(Res.Xpn_BadPosition));
                } 
                if (start.IsReadOnly) { 
                    throw new InvalidOperationException(Res.GetString(Res.Xdom_Node_Modify_ReadOnly));
                } 
                DocumentXPathNavigator.DeleteToFollowingSibling(start.NextSibling, end);
            }
            XmlNode fragment0 = fragment[0];
            parent.ReplaceChild(fragment0, start); 
            for (int i = fragment.Count - 1; i >= 1; i--) {
                parent.InsertAfter(fragment[i], fragment0); 
            } 
            navigator.ResetPosition(fragment0);
        } 

        public override void Flush() {
            // nop
        } 

        IDictionary IXmlNamespaceResolver.GetNamespacesInScope(XmlNamespaceScope scope) { 
            return namespaceManager.GetNamespacesInScope(scope); 
        }
 
        string IXmlNamespaceResolver.LookupNamespace(string prefix) {
            return namespaceManager.LookupNamespace(prefix);
        }
 
        string IXmlNamespaceResolver.LookupPrefix(string namespaceName) {
            return namespaceManager.LookupPrefix(namespaceName); 
        } 

        void AddAttribute(XmlAttribute attr, XmlNode parent) { 
            if (parent == null) {
                fragment.Add(attr);
            }
            else { 
                XmlElement elem = parent as XmlElement;
                if (elem == null) { 
                    throw new InvalidOperationException(); 
                }
                elem.Attributes.Append(attr); 
            }
        }

        void AddChild(XmlNode node, XmlNode parent) { 
            if (parent == null) {
                fragment.Add(node); 
            } 
            else {
                parent.AppendChild(node); 
            }
        }

        State StartState() { 
            XmlNodeType nodeType = XmlNodeType.None;
 
            switch (type) { 
                case DocumentXmlWriterType.InsertSiblingAfter:
                case DocumentXmlWriterType.InsertSiblingBefore: 
                    XmlNode parent = start.ParentNode;
                    if (parent != null) {
                        nodeType = parent.NodeType;
                    } 
                    if (nodeType == XmlNodeType.Document) {
                        return State.Prolog; 
                    } 
                    else if (nodeType == XmlNodeType.DocumentFragment)  {
                        return State.Fragment; 
                    }
                    break;
                case DocumentXmlWriterType.PrependChild:
                case DocumentXmlWriterType.AppendChild: 
                    nodeType = start.NodeType;
                    if (nodeType == XmlNodeType.Document) { 
                        return State.Prolog; 
                    }
                    else if (nodeType == XmlNodeType.DocumentFragment)  { 
                        return State.Fragment;
                    }
                    break;
                case DocumentXmlWriterType.AppendAttribute: 
                    return State.Attribute;
                case DocumentXmlWriterType.ReplaceToFollowingSibling: 
                    break; 
            }
            return State.Content; 
        }

        static State[] changeState = {
//          State.Error,    State.Attribute,State.Prolog,   State.Fragment, State.Content, 

// Method.XmlDeclaration: 
            State.Error,    State.Error,    State.Prolog,   State.Content,  State.Error, 
// Method.StartDocument:
            State.Error,    State.Error,    State.Error,    State.Error,    State.Error, 
// Method.EndDocument:
            State.Error,    State.Error,    State.Error,    State.Error,    State.Error,
// Method.DocType:
            State.Error,    State.Error,    State.Prolog,   State.Error,    State.Error, 
// Method.StartElement:
            State.Error,    State.Error,    State.Content,  State.Content,  State.Content, 
// Method.EndElement: 
            State.Error,    State.Error,    State.Error,    State.Error,    State.Content,
// Method.FullEndElement: 
            State.Error,    State.Error,    State.Error,    State.Error,    State.Content,
// Method.StartAttribute:
            State.Error,    State.Content,  State.Error,    State.Error,    State.Content,
// Method.EndAttribute: 
            State.Error,    State.Error,    State.Error,    State.Error,    State.Content,
// Method.StartNamespaceDeclaration: 
            State.Error,    State.Content,  State.Error,    State.Error,    State.Content, 
// Method.EndNamespaceDeclaration:
            State.Error,    State.Error,    State.Error,    State.Error,    State.Content, 
// Method.CData:
            State.Error,    State.Error,    State.Error,    State.Content,  State.Content,
// Method.Comment:
            State.Error,    State.Error,    State.Prolog,   State.Content,  State.Content, 
// Method.ProcessingInstruction:
            State.Error,    State.Error,    State.Prolog,   State.Content,  State.Content, 
// Method.EntityRef: 
            State.Error,    State.Error,    State.Error,    State.Content,  State.Content,
// Method.Whitespace: 
            State.Error,    State.Error,    State.Prolog,   State.Content,  State.Content,
// Method.String:
            State.Error,    State.Error,    State.Error,    State.Content,  State.Content,
        }; 

        void VerifyState(Method method) { 
            state = changeState[(int)method * (int)State.Last + (int)state]; 
            if (state == State.Error) {
                throw new InvalidOperationException(Res.GetString(Res.Xml_ClosedOrError)); 
            }
        }
    }
} 

// File provided for Reference Use Only by Microsoft Corporation (c) 2007.
//------------------------------------------------------------------------------ 
// 
//     Copyright (c) Microsoft Corporation.  All rights reserved.
// 
// [....] 
//-----------------------------------------------------------------------------
 
using System; 
using System.Collections;
using System.Collections.Generic; 
using System.Diagnostics;
using System.Xml.Schema;

namespace System.Xml { 
    enum DocumentXmlWriterType {
        InsertSiblingAfter, 
        InsertSiblingBefore, 
        PrependChild,
        AppendChild, 
        AppendAttribute,
        ReplaceToFollowingSibling,
    }
 
    // Implements a XmlWriter that augments a XmlDocument.
    sealed class DocumentXmlWriter : XmlRawWriter, IXmlNamespaceResolver { 
        enum State { 
            Error,
            Attribute, 
            Prolog,
            Fragment,
            Content,
 
            Last, // always last
        } 
 
        enum Method {
            WriteXmlDeclaration, 
            WriteStartDocument,
            WriteEndDocument,
            WriteDocType,
            WriteStartElement, 
            WriteEndElement,
            WriteFullEndElement, 
            WriteStartAttribute, 
            WriteEndAttribute,
            WriteStartNamespaceDeclaration, 
            WriteEndNamespaceDeclaration,
            WriteCData,
            WriteComment,
            WriteProcessingInstruction, 
            WriteEntityRef,
            WriteWhitespace, 
            WriteString, 
        }
 
        DocumentXmlWriterType type; // writer type
        XmlNode start; // context node
        XmlDocument document; // context document
        XmlNamespaceManager namespaceManager; // context namespace manager 
        State state; // current state
        XmlNode write; // current node 
        List fragment; // top level node cache 
        XmlWriterSettings settings; // wrapping writer settings
        DocumentXPathNavigator navigator; // context for replace 
        XmlNode end; // context for replace

        public DocumentXmlWriter(DocumentXmlWriterType type, XmlNode start, XmlDocument document) {
            this.type = type; 
            this.start = start;
            this.document = document; 
 
            state = StartState();
            fragment = new List(); 
            settings = new XmlWriterSettings();
            settings.ReadOnly = false;
            settings.CheckCharacters = false;
            settings.CloseOutput = false; 
            settings.ConformanceLevel = (state == State.Prolog ? ConformanceLevel.Document : ConformanceLevel.Fragment);
            settings.ReadOnly = true; 
        } 

        public XmlNamespaceManager NamespaceManager { 
            set {
                namespaceManager = value;
            }
        } 

        public override XmlWriterSettings Settings { 
            get { 
                return settings;
            } 
        }

        internal void SetSettings(XmlWriterSettings value) {
            settings = value; 
        }
 
        public DocumentXPathNavigator Navigator { 
            set {
                navigator = value; 
            }
        }

        public XmlNode EndNode { 
            set {
                end = value; 
            } 
        }
 
        internal override void WriteXmlDeclaration(XmlStandalone standalone) {
            VerifyState(Method.WriteXmlDeclaration);
            if (standalone != XmlStandalone.Omit) {
                XmlNode node = document.CreateXmlDeclaration("1.0", string.Empty, standalone == XmlStandalone.Yes ? "yes" : "no"); 
                AddChild(node, write);
            } 
        } 

        internal override void WriteXmlDeclaration(string xmldecl) { 
            VerifyState(Method.WriteXmlDeclaration);
            string version, encoding, standalone;
            XmlLoader.ParseXmlDeclarationValue(xmldecl, out version, out encoding, out standalone);
            XmlNode node = document.CreateXmlDeclaration(version, encoding, standalone); 
            AddChild(node, write);
        } 
 
        public override void WriteStartDocument() {
            VerifyState(Method.WriteStartDocument); 
        }

        public override void WriteStartDocument(bool standalone) {
            VerifyState(Method.WriteStartDocument); 
        }
 
        public override void WriteEndDocument() { 
            VerifyState(Method.WriteEndDocument);
        } 

        public override void WriteDocType(string name, string pubid, string sysid, string subset) {
            VerifyState(Method.WriteDocType);
            XmlNode node = document.CreateDocumentType(name, pubid, sysid, subset); 
            AddChild(node, write);
        } 
 
        public override void WriteStartElement(string prefix, string localName, string ns) {
            VerifyState(Method.WriteStartElement); 
            XmlNode node = document.CreateElement(prefix, localName, ns);
            AddChild(node, write);
            write = node;
        } 

        public override void WriteEndElement() { 
            VerifyState(Method.WriteEndElement); 
            if (write == null) {
                throw new InvalidOperationException(); 
            }
            write = write.ParentNode;
        }
 
        internal override void WriteEndElement(string prefix, string localName, string ns) {
            WriteEndElement(); 
        } 

        public override void WriteFullEndElement() { 
            VerifyState(Method.WriteFullEndElement);
            XmlElement elem = write as XmlElement;
            if (elem == null) {
                throw new InvalidOperationException(); 
            }
            elem.IsEmpty = false; 
            write = elem.ParentNode; 
        }
 
        internal override void WriteFullEndElement(string prefix, string localName, string ns) {
            WriteFullEndElement();
        }
 
        internal override void StartElementContent() {
            // nop 
        } 

        public override void WriteStartAttribute(string prefix, string localName, string ns) { 
            VerifyState(Method.WriteStartAttribute);
            XmlAttribute attr = document.CreateAttribute(prefix, localName, ns);
            AddAttribute(attr, write);
            write = attr; 
        }
 
        public override void WriteEndAttribute() { 
            VerifyState(Method.WriteEndAttribute);
            XmlAttribute attr = write as XmlAttribute; 
            if (attr == null) {
                throw new InvalidOperationException();
            }
            if (!attr.HasChildNodes) { 
                XmlNode node = document.CreateTextNode(string.Empty);
                AddChild(node, attr); 
            } 
            write = attr.OwnerElement;
        } 

        internal override void WriteNamespaceDeclaration(string prefix, string ns) {
            this.WriteStartNamespaceDeclaration(prefix);
            this.WriteString(ns); 
            this.WriteEndNamespaceDeclaration();
        } 
 
        internal override bool SupportsNamespaceDeclarationInChunks {
            get { 
                return true;
            }
        }
 
        internal override void WriteStartNamespaceDeclaration(string prefix) {
            VerifyState(Method.WriteStartNamespaceDeclaration); 
            XmlAttribute attr; 
            if (prefix.Length == 0) {
                attr = document.CreateAttribute(prefix, document.strXmlns, document.strReservedXmlns); 
            }
            else {
                attr = document.CreateAttribute(document.strXmlns, prefix, document.strReservedXmlns);
            } 
            AddAttribute(attr, write);
            write = attr; 
        } 

        internal override void WriteEndNamespaceDeclaration() { 
            VerifyState(Method.WriteEndNamespaceDeclaration);
            XmlAttribute attr = write as XmlAttribute;
            if (attr == null) {
                throw new InvalidOperationException(); 
            }
            if (!attr.HasChildNodes) { 
                XmlNode node = document.CreateTextNode(string.Empty); 
                AddChild(node, attr);
            } 
            write = attr.OwnerElement;
        }

        public override void WriteCData(string text) { 
            VerifyState(Method.WriteCData);
            XmlConvert.VerifyCharData(text, ExceptionType.ArgumentException); 
            XmlNode node = document.CreateCDataSection(text); 
            AddChild(node, write);
        } 

        public override void WriteComment(string text) {
            VerifyState(Method.WriteComment);
            XmlConvert.VerifyCharData(text, ExceptionType.ArgumentException); 
            XmlNode node = document.CreateComment(text);
            AddChild(node, write); 
        } 

        public override void WriteProcessingInstruction(string name, string text) { 
            VerifyState(Method.WriteProcessingInstruction);
            XmlConvert.VerifyCharData(text, ExceptionType.ArgumentException);
            XmlNode node = document.CreateProcessingInstruction(name, text);
            AddChild(node, write); 
        }
 
        public override void WriteEntityRef(string name) { 
            VerifyState(Method.WriteEntityRef);
            XmlNode node = document.CreateEntityReference(name); 
            AddChild(node, write);
            //
        }
 
        public override void WriteCharEntity(char ch) {
            WriteString(new string(ch, 1)); 
        } 

        public override void WriteWhitespace(string text) { 
            VerifyState(Method.WriteWhitespace);
            XmlConvert.VerifyCharData(text, ExceptionType.ArgumentException);
            if (document.PreserveWhitespace) {
                XmlNode node = document.CreateWhitespace(text); 
                AddChild(node, write);
            } 
        } 

        public override void WriteString(string text) { 
            VerifyState(Method.WriteString);
            XmlConvert.VerifyCharData(text, ExceptionType.ArgumentException);
            XmlNode node = document.CreateTextNode(text);
            AddChild(node, write); 
        }
 
        public override void WriteSurrogateCharEntity(char lowCh, char highCh) { 
            WriteString(new string(new char[] {highCh, lowCh}));
        } 

        public override void WriteChars(char[] buffer, int index, int count) {
            WriteString(new string(buffer, index, count));
        } 

        public override void WriteRaw(char[] buffer, int index, int count) { 
            WriteString(new string(buffer, index, count)); 
        }
 
        public override void WriteRaw(string data) {
            WriteString(data);
        }
 
        public override void Close() {
            // nop 
        } 

        internal override void Close(WriteState currentState) { 
            if (currentState == WriteState.Error) {
                return;
            }
            try { 
                switch (type) {
                    case DocumentXmlWriterType.InsertSiblingAfter: 
                        XmlNode parent = start.ParentNode; 
                        if (parent == null) {
                            throw new InvalidOperationException(Res.GetString(Res.Xpn_MissingParent)); 
                        }
                        for (int i = fragment.Count - 1; i >= 0; i--) {
                            parent.InsertAfter(fragment[i], start);
                        } 
                        break;
                    case DocumentXmlWriterType.InsertSiblingBefore: 
                        parent = start.ParentNode; 
                        if (parent == null) {
                            throw new InvalidOperationException(Res.GetString(Res.Xpn_MissingParent)); 
                        }
                        for (int i = 0; i < fragment.Count; i++) {
                            parent.InsertBefore(fragment[i], start);
                        } 
                        break;
                    case DocumentXmlWriterType.PrependChild: 
                        for (int i = fragment.Count - 1; i >= 0; i--) { 
                            start.PrependChild(fragment[i]);
                        } 
                        break;
                    case DocumentXmlWriterType.AppendChild:
                        for (int i = 0; i < fragment.Count; i++) {
                            start.AppendChild(fragment[i]); 
                        }
                        break; 
                    case DocumentXmlWriterType.AppendAttribute: 
                        CloseWithAppendAttribute();
                        break; 
                    case DocumentXmlWriterType.ReplaceToFollowingSibling:
                        if (fragment.Count == 0) {
                            throw new InvalidOperationException(Res.GetString(Res.Xpn_NoContent));
                        } 
                        CloseWithReplaceToFollowingSibling();
                        break; 
                } 
            }
            finally { 
                fragment.Clear();
            }
        }
 
        private void CloseWithAppendAttribute() {
            XmlElement elem = start as XmlElement; 
            Debug.Assert(elem != null); 
            XmlAttributeCollection attrs = elem.Attributes;
            for (int i = 0; i < fragment.Count; i++) { 
                XmlAttribute attr = fragment[i] as XmlAttribute;
                Debug.Assert(attr != null);
                int offset = attrs.FindNodeOffsetNS(attr);
                if (offset != -1 
                    && ((XmlAttribute)attrs.Nodes[offset]).Specified) {
                    throw new XmlException(Res.Xml_DupAttributeName, attr.Prefix.Length == 0 ? attr.LocalName : string.Concat(attr.Prefix, ":", attr.LocalName)); 
                } 
            }
            for (int i = 0; i < fragment.Count; i++) { 
                XmlAttribute attr = fragment[i] as XmlAttribute;
                Debug.Assert(attr != null);
                attrs.Append(attr);
            } 
        }
 
        private void CloseWithReplaceToFollowingSibling() { 
            XmlNode parent = start.ParentNode;
            if (parent == null) { 
                throw new InvalidOperationException(Res.GetString(Res.Xpn_MissingParent));
            }
            if (start != end) {
                if (!DocumentXPathNavigator.IsFollowingSibling(start, end)) { 
                    throw new InvalidOperationException(Res.GetString(Res.Xpn_BadPosition));
                } 
                if (start.IsReadOnly) { 
                    throw new InvalidOperationException(Res.GetString(Res.Xdom_Node_Modify_ReadOnly));
                } 
                DocumentXPathNavigator.DeleteToFollowingSibling(start.NextSibling, end);
            }
            XmlNode fragment0 = fragment[0];
            parent.ReplaceChild(fragment0, start); 
            for (int i = fragment.Count - 1; i >= 1; i--) {
                parent.InsertAfter(fragment[i], fragment0); 
            } 
            navigator.ResetPosition(fragment0);
        } 

        public override void Flush() {
            // nop
        } 

        IDictionary IXmlNamespaceResolver.GetNamespacesInScope(XmlNamespaceScope scope) { 
            return namespaceManager.GetNamespacesInScope(scope); 
        }
 
        string IXmlNamespaceResolver.LookupNamespace(string prefix) {
            return namespaceManager.LookupNamespace(prefix);
        }
 
        string IXmlNamespaceResolver.LookupPrefix(string namespaceName) {
            return namespaceManager.LookupPrefix(namespaceName); 
        } 

        void AddAttribute(XmlAttribute attr, XmlNode parent) { 
            if (parent == null) {
                fragment.Add(attr);
            }
            else { 
                XmlElement elem = parent as XmlElement;
                if (elem == null) { 
                    throw new InvalidOperationException(); 
                }
                elem.Attributes.Append(attr); 
            }
        }

        void AddChild(XmlNode node, XmlNode parent) { 
            if (parent == null) {
                fragment.Add(node); 
            } 
            else {
                parent.AppendChild(node); 
            }
        }

        State StartState() { 
            XmlNodeType nodeType = XmlNodeType.None;
 
            switch (type) { 
                case DocumentXmlWriterType.InsertSiblingAfter:
                case DocumentXmlWriterType.InsertSiblingBefore: 
                    XmlNode parent = start.ParentNode;
                    if (parent != null) {
                        nodeType = parent.NodeType;
                    } 
                    if (nodeType == XmlNodeType.Document) {
                        return State.Prolog; 
                    } 
                    else if (nodeType == XmlNodeType.DocumentFragment)  {
                        return State.Fragment; 
                    }
                    break;
                case DocumentXmlWriterType.PrependChild:
                case DocumentXmlWriterType.AppendChild: 
                    nodeType = start.NodeType;
                    if (nodeType == XmlNodeType.Document) { 
                        return State.Prolog; 
                    }
                    else if (nodeType == XmlNodeType.DocumentFragment)  { 
                        return State.Fragment;
                    }
                    break;
                case DocumentXmlWriterType.AppendAttribute: 
                    return State.Attribute;
                case DocumentXmlWriterType.ReplaceToFollowingSibling: 
                    break; 
            }
            return State.Content; 
        }

        static State[] changeState = {
//          State.Error,    State.Attribute,State.Prolog,   State.Fragment, State.Content, 

// Method.XmlDeclaration: 
            State.Error,    State.Error,    State.Prolog,   State.Content,  State.Error, 
// Method.StartDocument:
            State.Error,    State.Error,    State.Error,    State.Error,    State.Error, 
// Method.EndDocument:
            State.Error,    State.Error,    State.Error,    State.Error,    State.Error,
// Method.DocType:
            State.Error,    State.Error,    State.Prolog,   State.Error,    State.Error, 
// Method.StartElement:
            State.Error,    State.Error,    State.Content,  State.Content,  State.Content, 
// Method.EndElement: 
            State.Error,    State.Error,    State.Error,    State.Error,    State.Content,
// Method.FullEndElement: 
            State.Error,    State.Error,    State.Error,    State.Error,    State.Content,
// Method.StartAttribute:
            State.Error,    State.Content,  State.Error,    State.Error,    State.Content,
// Method.EndAttribute: 
            State.Error,    State.Error,    State.Error,    State.Error,    State.Content,
// Method.StartNamespaceDeclaration: 
            State.Error,    State.Content,  State.Error,    State.Error,    State.Content, 
// Method.EndNamespaceDeclaration:
            State.Error,    State.Error,    State.Error,    State.Error,    State.Content, 
// Method.CData:
            State.Error,    State.Error,    State.Error,    State.Content,  State.Content,
// Method.Comment:
            State.Error,    State.Error,    State.Prolog,   State.Content,  State.Content, 
// Method.ProcessingInstruction:
            State.Error,    State.Error,    State.Prolog,   State.Content,  State.Content, 
// Method.EntityRef: 
            State.Error,    State.Error,    State.Error,    State.Content,  State.Content,
// Method.Whitespace: 
            State.Error,    State.Error,    State.Prolog,   State.Content,  State.Content,
// Method.String:
            State.Error,    State.Error,    State.Error,    State.Content,  State.Content,
        }; 

        void VerifyState(Method method) { 
            state = changeState[(int)method * (int)State.Last + (int)state]; 
            if (state == State.Error) {
                throw new InvalidOperationException(Res.GetString(Res.Xml_ClosedOrError)); 
            }
        }
    }
} 

// File provided for Reference Use Only by Microsoft Corporation (c) 2007.

                        

Link Menu

Network programming in C#, Network Programming in VB.NET, Network Programming in .NET
This book is available now!
Buy at Amazon US or
Buy at Amazon UK