XmlDocument.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 / XmlDocument.cs / 1305376 / XmlDocument.cs

                            //------------------------------------------------------------------------------ 
// 
//     Copyright (c) Microsoft Corporation.  All rights reserved.
// 
// [....] 
//-----------------------------------------------------------------------------
 
namespace System.Xml 
{
    using System; 
    using System.Collections;
    using System.Diagnostics;
    using System.IO;
    using System.Text; 
    using System.Xml.Schema;
    using System.Xml.XPath; 
    using System.Security; 
    using System.Security.Permissions;
    using System.Globalization; 
    using System.Runtime.Versioning;

    // Represents an entire document. An XmlDocument contains XML data.
    public class XmlDocument: XmlNode { 
        private XmlImplementation implementation;
        private DomNameTable domNameTable; // hash table of XmlName 
        private XmlLinkedNode lastChild; 
        private XmlNamedNodeMap entities;
        private Hashtable htElementIdMap; 
        private Hashtable htElementIDAttrDecl; //key: id; object: the ArrayList of the elements that have the same id (connected or disconnected)
        private SchemaInfo schemaInfo;
        private XmlSchemaSet schemas; // schemas associated with the cache
        private bool reportValidity; 
        //This variable represents the actual loading status. Since, IsLoading will
        //be manipulated soemtimes for adding content to EntityReference this variable 
        //has been added which would always represent the loading status of document. 
        private bool actualLoadingStatus;
 
        private XmlNodeChangedEventHandler onNodeInsertingDelegate;
        private XmlNodeChangedEventHandler onNodeInsertedDelegate;
        private XmlNodeChangedEventHandler onNodeRemovingDelegate;
        private XmlNodeChangedEventHandler onNodeRemovedDelegate; 
        private XmlNodeChangedEventHandler onNodeChangingDelegate;
        private XmlNodeChangedEventHandler onNodeChangedDelegate; 
 
        // false if there are no ent-ref present, true if ent-ref nodes are or were present (i.e. if all ent-ref were removed, the doc will not clear this flag)
        internal bool fEntRefNodesPresent; 
        internal bool fCDataNodesPresent;

        private bool preserveWhitespace;
        private bool isLoading; 

        // special name strings for 
        internal string strDocumentName; 
        internal string strDocumentFragmentName;
        internal string strCommentName; 
        internal string strTextName;
        internal string strCDataSectionName;
        internal string strEntityName;
        internal string strID; 
        internal string strXmlns;
        internal string strXml; 
        internal string strSpace; 
        internal string strLang;
        internal string strEmpty; 

        internal string strNonSignificantWhitespaceName;
        internal string strSignificantWhitespaceName;
        internal string strReservedXmlns; 
        internal string strReservedXml;
 
        internal String baseURI; 

        private XmlResolver resolver; 
        internal bool       bSetResolver;
        internal object     objLock;

        private XmlAttribute namespaceXml; 

        static internal EmptyEnumerator EmptyEnumerator = new EmptyEnumerator(); 
        static internal IXmlSchemaInfo NotKnownSchemaInfo = new XmlSchemaInfo(XmlSchemaValidity.NotKnown); 
        static internal IXmlSchemaInfo ValidSchemaInfo = new XmlSchemaInfo(XmlSchemaValidity.Valid);
        static internal IXmlSchemaInfo InvalidSchemaInfo = new XmlSchemaInfo(XmlSchemaValidity.Invalid); 

        // Initializes a new instance of the XmlDocument class.
        public XmlDocument(): this( new XmlImplementation() ) {
        } 

        // Initializes a new instance 
        // of the XmlDocument class with the specified XmlNameTable. 
        public XmlDocument( XmlNameTable nt ) : this( new XmlImplementation( nt ) ) {
        } 

        protected internal XmlDocument( XmlImplementation imp ): base() {

            implementation = imp; 
            domNameTable = new DomNameTable( this );
 
            // force the following string instances to be default in the nametable 
            XmlNameTable nt = this.NameTable;
            nt.Add( string.Empty ); 
            strDocumentName = nt.Add( "#document" );
            strDocumentFragmentName  = nt.Add( "#document-fragment" );
            strCommentName = nt.Add( "#comment" );
            strTextName = nt.Add( "#text" ); 
            strCDataSectionName = nt.Add( "#cdata-section" );
            strEntityName = nt.Add( "#entity" ); 
            strID = nt.Add( "id" ); 
            strNonSignificantWhitespaceName = nt.Add( "#whitespace" );
            strSignificantWhitespaceName = nt.Add( "#significant-whitespace" ); 
            strXmlns = nt.Add( "xmlns" );
            strXml = nt.Add(  "xml" );
            strSpace = nt.Add(  "space" );
            strLang = nt.Add(  "lang" ); 
            strReservedXmlns = nt.Add( XmlReservedNs.NsXmlNs );
            strReservedXml = nt.Add( XmlReservedNs.NsXml ); 
            strEmpty = nt.Add( String.Empty ); 
            baseURI = String.Empty;
 
            objLock = new object();
        }

        internal SchemaInfo DtdSchemaInfo { 
            get { return schemaInfo; }
            set { schemaInfo = value; } 
        } 

        // NOTE: This does not correctly check start name char, but we cannot change it since it would be a breaking change. 
        internal static void CheckName( String name ) {
            int endPos = ValidateNames.ParseNmtoken( name, 0 );
            if (endPos < name.Length) {
                throw new XmlException(Res.Xml_BadNameChar, XmlException.BuildCharExceptionArgs(name, endPos)); 
            }
        } 
 
        internal XmlName AddXmlName(string prefix, string localName, string namespaceURI, IXmlSchemaInfo schemaInfo) {
            XmlName n = domNameTable.AddName(prefix, localName, namespaceURI, schemaInfo); 
            Debug.Assert( (prefix == null) ? (n.Prefix.Length == 0) : (prefix == n.Prefix) );
            Debug.Assert( n.LocalName == localName );
            Debug.Assert( (namespaceURI == null) ? (n.NamespaceURI.Length == 0) : (n.NamespaceURI == namespaceURI) );
            return n; 
        }
 
        internal XmlName GetXmlName(string prefix, string localName, string namespaceURI, IXmlSchemaInfo schemaInfo) { 
            XmlName n = domNameTable.GetName(prefix, localName, namespaceURI, schemaInfo);
            Debug.Assert(n == null || ((prefix == null) ? (n.Prefix.Length == 0) : (prefix == n.Prefix))); 
            Debug.Assert(n == null || n.LocalName == localName);
            Debug.Assert(n == null || ((namespaceURI == null) ? (n.NamespaceURI.Length == 0) : (n.NamespaceURI == namespaceURI)));
            return n;
        } 

        internal XmlName AddAttrXmlName(string prefix, string localName, string namespaceURI, IXmlSchemaInfo schemaInfo) { 
            XmlName xmlName = AddXmlName(prefix, localName, namespaceURI, schemaInfo); 
            Debug.Assert( (prefix == null) ? (xmlName.Prefix.Length == 0) : (prefix == xmlName.Prefix) );
            Debug.Assert( xmlName.LocalName == localName ); 
            Debug.Assert( (namespaceURI == null) ? (xmlName.NamespaceURI.Length == 0) : (xmlName.NamespaceURI == namespaceURI) );

            if ( !this.IsLoading ) {
                // Use atomized versions instead of prefix, localName and nsURI 
                object oPrefix       = xmlName.Prefix;
                object oNamespaceURI = xmlName.NamespaceURI; 
                object oLocalName    = xmlName.LocalName; 
                if ( ( oPrefix == (object)strXmlns || ( oPrefix == (object)strEmpty && oLocalName == (object)strXmlns ) ) ^ ( oNamespaceURI == (object)strReservedXmlns ) )
                    throw new ArgumentException( Res.GetString( Res.Xdom_Attr_Reserved_XmlNS, namespaceURI ) ); 
            }
            return xmlName;
        }
 
        internal bool AddIdInfo( XmlName eleName, XmlName attrName ) {
            //when XmlLoader call XmlDocument.AddInfo, the element.XmlName and attr.XmlName 
            //have already been replaced with the ones that don't have namespace values (or just 
            //string.Empty) because in DTD, the namespace is not supported
            if ( htElementIDAttrDecl == null || htElementIDAttrDecl[eleName] == null ) { 
                if ( htElementIDAttrDecl == null )
                    htElementIDAttrDecl = new Hashtable();
                htElementIDAttrDecl.Add(eleName, attrName);
                return true; 
            }
            return false; 
        } 

        private XmlName GetIDInfoByElement_(XmlName eleName) 
        {
            //When XmlDocument is getting the IDAttribute for a given element,
            //we need only compare the prefix and localname of element.XmlName with
            //the registered htElementIDAttrDecl. 
            XmlName newName = GetXmlName(eleName.Prefix, eleName.LocalName, string.Empty, null);
            if (newName != null) { 
                return (XmlName)(htElementIDAttrDecl[newName]); 
            }
            return null; 
        }

        internal XmlName GetIDInfoByElement( XmlName eleName ) {
            if (htElementIDAttrDecl == null) 
                return null;
            else 
                return GetIDInfoByElement_(eleName); 
        }
 
        private WeakReference GetElement(ArrayList elementList, XmlElement elem) {
            ArrayList gcElemRefs = new ArrayList();
            foreach( WeakReference elemRef in elementList) {
                if ( !elemRef.IsAlive) 
                    //take notes on the garbage collected nodes
                    gcElemRefs.Add(elemRef); 
                else { 
                    if ((XmlElement)(elemRef.Target) == elem)
                        return elemRef; 
                }
            }
            //Clear out the gced elements
            foreach( WeakReference elemRef in gcElemRefs) 
                elementList.Remove(elemRef);
            return null; 
        } 

        internal void AddElementWithId( string id, XmlElement elem ) { 
            if (htElementIdMap == null || !htElementIdMap.Contains(id)) {
                if ( htElementIdMap == null )
                    htElementIdMap = new Hashtable();
                ArrayList elementList = new ArrayList(); 
                elementList.Add(new WeakReference(elem));
                htElementIdMap.Add(id, elementList); 
            } 
            else {
                // there are other element(s) that has the same id 
                ArrayList elementList = (ArrayList)(htElementIdMap[id]);
                if (GetElement(elementList, elem) == null)
                    elementList.Add(new WeakReference(elem));
            } 
        }
 
        internal void RemoveElementWithId( string id, XmlElement elem ) { 
            if (htElementIdMap != null && htElementIdMap.Contains(id)) {
                ArrayList elementList = (ArrayList)(htElementIdMap[id]); 
                WeakReference elemRef = GetElement(elementList, elem);
                if (elemRef != null) {
                    elementList.Remove(elemRef);
                    if (elementList.Count == 0) 
                        htElementIdMap.Remove(id);
                } 
            } 
        }
 

        // Creates a duplicate of this node.
        public override XmlNode CloneNode( bool deep ) {
            XmlDocument clone = Implementation.CreateDocument(); 
            clone.SetBaseURI(this.baseURI);
            if (deep) 
                clone.ImportChildren( this, clone, deep ); 

            return clone; 
        }

        // Gets the type of the current node.
        public override XmlNodeType NodeType { 
            get { return XmlNodeType.Document; }
        } 
 
        public override XmlNode ParentNode {
            get { return null; } 
        }

        // Gets the node for the DOCTYPE declaration.
        public virtual XmlDocumentType DocumentType { 
            get { return(XmlDocumentType) FindChild( XmlNodeType.DocumentType ); }
        } 
 
        internal virtual XmlDeclaration Declaration {
            get { 
                if ( HasChildNodes ) {
                    XmlDeclaration dec = FirstChild as XmlDeclaration;
                    return dec;
                } 
                return null;
            } 
        } 

        // Gets the XmlImplementation object for this document. 
        public XmlImplementation Implementation {
            get { return this.implementation; }
        }
 
        // Gets the name of the node.
        public override String Name  { 
            get { return strDocumentName; } 
        }
 
        // Gets the name of the current node without the namespace prefix.
        public override String LocalName {
            get { return strDocumentName; }
        } 

        // Gets the root XmlElement for the document. 
        public XmlElement DocumentElement { 
            get { return(XmlElement)FindChild(XmlNodeType.Element); }
        } 

        internal override bool IsContainer {
            get { return true; }
        } 

        internal override XmlLinkedNode LastNode 
        { 
            get { return lastChild; }
            set { lastChild = value; } 
        }

        // Gets the XmlDocument that contains this node.
        public override XmlDocument OwnerDocument 
        {
            get { return null; } 
        } 

        public XmlSchemaSet Schemas { 
            get {
                if (schemas == null) {
                    schemas = new XmlSchemaSet(NameTable);
                } 
                return schemas;
            } 
 
            set {
                schemas = value; 
            }
        }

        internal bool CanReportValidity { 
            get { return reportValidity; }
        } 
 
        internal bool HasSetResolver {
            get { return bSetResolver; } 
        }

        internal XmlResolver GetResolver() {
           return resolver; 
        }
 
        public virtual XmlResolver XmlResolver { 
            set {
                if ( value != null ) { 
                    try {
                        new NamedPermissionSet( "FullTrust" ).Demand();
                    }
                    catch ( SecurityException e ) { 
                        throw new SecurityException( Res.GetString( Res.Xml_UntrustedCodeSettingResolver ), e );
                    } 
                } 

                resolver = value; 
                if ( !bSetResolver )
                    bSetResolver = true;

                XmlDocumentType dtd = this.DocumentType; 
                if ( dtd != null ) {
                    dtd.DtdSchemaInfo = null; 
                } 
            }
        } 
        internal override bool IsValidChildType( XmlNodeType type ) {
            switch ( type ) {
                case XmlNodeType.ProcessingInstruction:
                case XmlNodeType.Comment: 
                case XmlNodeType.Whitespace:
                case XmlNodeType.SignificantWhitespace: 
                    return true; 

                case XmlNodeType.DocumentType: 
                    if ( DocumentType != null )
                        throw new InvalidOperationException( Res.GetString(Res.Xdom_DualDocumentTypeNode) );
                    return true;
 
                case XmlNodeType.Element:
                    if ( DocumentElement != null ) 
                        throw new InvalidOperationException( Res.GetString(Res.Xdom_DualDocumentElementNode) ); 
                    return true;
 
                case XmlNodeType.XmlDeclaration:
                    if ( Declaration != null )
                        throw new InvalidOperationException( Res.GetString(Res.Xdom_DualDeclarationNode) );
                    return true; 

                default: 
                    return false; 
            }
        } 
        // the function examines all the siblings before the refNode
        //  if any of the nodes has type equals to "nt", return true; otherwise, return false;
        private bool HasNodeTypeInPrevSiblings( XmlNodeType nt, XmlNode refNode ) {
            if ( refNode == null ) 
                return false;
 
            XmlNode node = null; 
            if ( refNode.ParentNode != null )
                node = refNode.ParentNode.FirstChild; 
            while ( node != null ) {
                if ( node.NodeType == nt )
                    return true;
                if ( node == refNode ) 
                    break;
                node = node.NextSibling; 
            } 
            return false;
        } 

        // the function examines all the siblings after the refNode
        //  if any of the nodes has the type equals to "nt", return true; otherwise, return false;
        private bool HasNodeTypeInNextSiblings( XmlNodeType nt, XmlNode refNode ) { 
            XmlNode node = refNode;
            while ( node != null ) { 
                if ( node.NodeType == nt ) 
                    return true;
                node = node.NextSibling; 
            }
            return false;
        }
 
        internal override bool CanInsertBefore( XmlNode newChild, XmlNode refChild ) {
            if ( refChild == null ) 
                refChild = FirstChild; 

            if ( refChild == null ) 
                return true;

            switch ( newChild.NodeType ) {
                case XmlNodeType.XmlDeclaration: 
                    return ( refChild == FirstChild );
 
                case XmlNodeType.ProcessingInstruction: 
                case XmlNodeType.Comment:
                    return refChild.NodeType != XmlNodeType.XmlDeclaration; 

                case XmlNodeType.DocumentType: {
                    if ( refChild.NodeType != XmlNodeType.XmlDeclaration ) {
                        //if refChild is not the XmlDeclaration node, only need to go through the sibling before and including refChild to 
                        //  make sure no Element ( rootElem node ) before the current position
                        return !HasNodeTypeInPrevSiblings( XmlNodeType.Element, refChild.PreviousSibling ); 
                    } 
                }
                break; 

                case XmlNodeType.Element: {
                    if ( refChild.NodeType != XmlNodeType.XmlDeclaration ) {
                        //if refChild is not the XmlDeclaration node, only need to go through the siblings after and including the refChild to 
                        //  make sure no DocType node and XmlDeclaration node after the current posistion.
                        return !HasNodeTypeInNextSiblings( XmlNodeType.DocumentType, refChild ); 
                    } 
                }
                break; 
            }

            return false;
        } 

        internal override bool CanInsertAfter( XmlNode newChild, XmlNode refChild ) { 
            if ( refChild == null ) 
                refChild = LastChild;
 
            if ( refChild == null )
                return true;

            switch ( newChild.NodeType ) { 
                case XmlNodeType.ProcessingInstruction:
                case XmlNodeType.Comment: 
                case XmlNodeType.Whitespace: 
                case XmlNodeType.SignificantWhitespace:
                    return true; 

                case XmlNodeType.DocumentType: {
                    //we will have to go through all the siblings before the refChild just to make sure no Element node ( rootElem )
                    //  before the current position 
                    return !HasNodeTypeInPrevSiblings( XmlNodeType.Element, refChild );
                } 
 
                case XmlNodeType.Element: {
                    return !HasNodeTypeInNextSiblings( XmlNodeType.DocumentType, refChild.NextSibling ); 
                }

            }
 
            return false;
        } 
 
        // Creates an XmlAttribute with the specified name.
        public XmlAttribute CreateAttribute( String name ) { 
            String prefix = String.Empty;
            String localName = String.Empty;
            String namespaceURI = String.Empty;
 
            SplitName( name, out prefix, out localName );
 
            SetDefaultNamespace( prefix, localName, ref namespaceURI ); 

            return CreateAttribute( prefix, localName, namespaceURI ); 
        }

        internal void SetDefaultNamespace( String prefix, String localName, ref String namespaceURI ) {
            if ( prefix == strXmlns || ( prefix.Length == 0 && localName == strXmlns ) ) { 
                namespaceURI = strReservedXmlns;
            } else if ( prefix == strXml ) { 
                namespaceURI = strReservedXml; 
            }
        } 

        // Creates a XmlCDataSection containing the specified data.
        public virtual XmlCDataSection CreateCDataSection( String data ) {
            fCDataNodesPresent = true; 
            return new XmlCDataSection( data, this );
        } 
 
        // Creates an XmlComment containing the specified data.
        public virtual XmlComment CreateComment( String data ) { 
            return new XmlComment( data, this );
        }

        // Returns a new XmlDocumentType object. 
        [PermissionSetAttribute( SecurityAction.InheritanceDemand, Name = "FullTrust" )]
        public virtual XmlDocumentType CreateDocumentType( string name, string publicId, string systemId, string internalSubset ) { 
            return new XmlDocumentType( name, publicId, systemId, internalSubset, this ); 
        }
 
        // Creates an XmlDocumentFragment.
        public virtual XmlDocumentFragment CreateDocumentFragment() {
            return new XmlDocumentFragment( this );
        } 

        // Creates an element with the specified name. 
        public XmlElement CreateElement( String name ) { 
            string prefix = String.Empty;
            string localName = String.Empty; 
            SplitName( name, out prefix, out localName );
            return CreateElement( prefix, localName, string.Empty );
        }
 

        internal void AddDefaultAttributes( XmlElement elem ) { 
            SchemaInfo schInfo = DtdSchemaInfo; 
            SchemaElementDecl ed = GetSchemaElementDecl( elem );
            if ( ed != null && ed.AttDefs != null ) { 
                IDictionaryEnumerator attrDefs = ed.AttDefs.GetEnumerator();
                while ( attrDefs.MoveNext() ) {
                    SchemaAttDef attdef = (SchemaAttDef)attrDefs.Value;
                    if ( attdef.Presence == SchemaDeclBase.Use.Default || 
                         attdef.Presence == SchemaDeclBase.Use.Fixed ) {
                         //build a default attribute and return 
                         string attrPrefix = string.Empty; 
                         string attrLocalname = attdef.Name.Name;
                         string attrNamespaceURI = string.Empty; 
                         if ( schInfo.SchemaType == SchemaType.DTD )
                            attrPrefix = attdef.Name.Namespace;
                         else {
                            attrPrefix = attdef.Prefix; 
                            attrNamespaceURI = attdef.Name.Namespace;
                         } 
                         XmlAttribute defattr = PrepareDefaultAttribute( attdef, attrPrefix, attrLocalname, attrNamespaceURI ); 
                         elem.SetAttributeNode( defattr );
                    } 
                }
            }
        }
 
        private SchemaElementDecl GetSchemaElementDecl( XmlElement elem ) {
            SchemaInfo schInfo = DtdSchemaInfo; 
            if ( schInfo != null ) { 
                //build XmlQualifiedName used to identify the element schema declaration
                XmlQualifiedName   qname = new XmlQualifiedName( elem.LocalName, schInfo.SchemaType == SchemaType.DTD ? elem.Prefix : elem.NamespaceURI ); 
                //get the schema info for the element
                SchemaElementDecl elemDecl;
                if ( schInfo.ElementDecls.TryGetValue(qname, out elemDecl) ) {
                    return elemDecl; 
                }
            } 
            return null; 
        }
 
        //Will be used by AddDeafulatAttributes() and GetDefaultAttribute() methods
        private XmlAttribute PrepareDefaultAttribute( SchemaAttDef attdef, string attrPrefix, string attrLocalname, string attrNamespaceURI ) {
            SetDefaultNamespace( attrPrefix, attrLocalname, ref attrNamespaceURI );
            XmlAttribute defattr = CreateDefaultAttribute( attrPrefix, attrLocalname, attrNamespaceURI ); 
            //parsing the default value for the default attribute
            defattr.InnerXml = attdef.DefaultValueRaw; 
            //during the expansion of the tree, the flag could be set to true, we need to set it back. 
            XmlUnspecifiedAttribute unspAttr = defattr as XmlUnspecifiedAttribute;
            if ( unspAttr != null ) { 
                unspAttr.SetSpecified( false );
            }
            return defattr;
        } 

        // Creates an XmlEntityReference with the specified name. 
        public virtual XmlEntityReference CreateEntityReference( String name ) { 
            return new XmlEntityReference( name, this );
        } 

        // Creates a XmlProcessingInstruction with the specified name
        // and data strings.
        public virtual XmlProcessingInstruction CreateProcessingInstruction( String target, String data ) { 
            return new XmlProcessingInstruction( target, data, this );
        } 
 
        // Creates a XmlDeclaration node with the specified values.
        public virtual XmlDeclaration CreateXmlDeclaration( String version, string encoding, string standalone ) { 
            return new XmlDeclaration( version, encoding, standalone, this );
        }

        // Creates an XmlText with the specified text. 
        public virtual XmlText CreateTextNode( String text ) {
            return new XmlText( text, this ); 
        } 

        // Creates a XmlSignificantWhitespace node. 
        public virtual XmlSignificantWhitespace CreateSignificantWhitespace( string text ) {
            return new XmlSignificantWhitespace( text, this );
        }
 
        public override XPathNavigator CreateNavigator() {
            return CreateNavigator(this); 
        } 

        internal protected virtual XPathNavigator CreateNavigator(XmlNode node) { 
            XmlNodeType nodeType = node.NodeType;
            XmlNode parent;
            XmlNodeType parentType;
 
            switch (nodeType) {
                case XmlNodeType.EntityReference: 
                case XmlNodeType.Entity: 
                case XmlNodeType.DocumentType:
                case XmlNodeType.Notation: 
                case XmlNodeType.XmlDeclaration:
                    return null;
                case XmlNodeType.Text:
                case XmlNodeType.CDATA: 
                case XmlNodeType.SignificantWhitespace:
                    parent = node.ParentNode; 
                    if (parent != null) { 
                        do {
                            parentType = parent.NodeType; 
                            if (parentType == XmlNodeType.Attribute) {
                                return null;
                            }
                            else if (parentType == XmlNodeType.EntityReference) { 
                                parent = parent.ParentNode;
                            } 
                            else { 
                                break;
                            } 
                        }
                        while (parent != null);
                    }
                    node = NormalizeText(node); 
                    break;
                case XmlNodeType.Whitespace: 
                    parent = node.ParentNode; 
                    if (parent != null) {
                        do { 
                            parentType = parent.NodeType;
                            if (parentType == XmlNodeType.Document
                                || parentType == XmlNodeType.Attribute) {
                                return null; 
                            }
                            else if (parentType == XmlNodeType.EntityReference) { 
                                parent = parent.ParentNode; 
                            }
                            else { 
                                break;
                            }
                        }
                        while (parent != null); 
                    }
                    node = NormalizeText(node); 
                    break; 
                default:
                    break; 
            }
            return new DocumentXPathNavigator(this, node);
        }
 
        internal static bool IsTextNode( XmlNodeType nt ) {
            switch( nt ) { 
                case XmlNodeType.Text: 
                case XmlNodeType.CDATA:
                case XmlNodeType.Whitespace: 
                case XmlNodeType.SignificantWhitespace:
                    return true;
                default:
                    return false; 
            }
        } 
 
        private XmlNode NormalizeText( XmlNode n ) {
            XmlNode retnode = null; 
            while( IsTextNode( n.NodeType ) ) {
                retnode = n;
                n = n.PreviousSibling;
 
                if( n == null ) {
                    XmlNode intnode = retnode; 
                    while ( true ) { 
                        if  ( intnode.ParentNode != null && intnode.ParentNode.NodeType == XmlNodeType.EntityReference ) {
                            if (intnode.ParentNode.PreviousSibling != null ) { 
                                n = intnode.ParentNode.PreviousSibling;
                                break;
                            }
                            else { 
                                intnode = intnode.ParentNode;
                                if( intnode == null ) 
                                    break; 
                            }
                        } 
                        else
                            break;
                    }
                } 

                if( n == null ) 
                    break; 
                while( n.NodeType == XmlNodeType.EntityReference ) {
                    n = n.LastChild; 
                }
            }
            return retnode;
        } 

        // Creates a XmlWhitespace node. 
        public virtual XmlWhitespace CreateWhitespace( string text ) { 
            return new XmlWhitespace( text, this );
        } 

        // Returns an XmlNodeList containing
        // a list of all descendant elements that match the specified name.
        public virtual XmlNodeList GetElementsByTagName( String name ) { 
            return new XmlElementList( this, name );
        } 
 
        // DOM Level 2
 
        // Creates an XmlAttribute with the specified LocalName
        // and NamespaceURI.
        [System.Runtime.TargetedPatchingOptOutAttribute("Performance critical to inline across NGen image boundaries")]
        public XmlAttribute CreateAttribute( String qualifiedName, String namespaceURI ) { 
            string prefix = String.Empty;
            string localName = String.Empty; 
 
            SplitName( qualifiedName, out prefix, out localName );
            return CreateAttribute( prefix, localName, namespaceURI ); 
        }

        // Creates an XmlElement with the specified LocalName and
        // NamespaceURI. 
        public XmlElement CreateElement( String qualifiedName, String namespaceURI ) {
            string prefix = String.Empty; 
            string localName = String.Empty; 
            SplitName( qualifiedName, out prefix, out localName );
            return CreateElement( prefix, localName, namespaceURI ); 
        }

        // Returns a XmlNodeList containing
        // a list of all descendant elements that match the specified name. 
        public virtual XmlNodeList GetElementsByTagName( String localName, String namespaceURI ) {
            return new XmlElementList( this, localName, namespaceURI ); 
        } 

        // Returns the XmlElement with the specified ID. 
        public virtual XmlElement GetElementById( string elementId ) {
            if (htElementIdMap != null) {
                ArrayList elementList = (ArrayList)(htElementIdMap[elementId]);
                if (elementList != null) { 
                    foreach (WeakReference elemRef in elementList) {
                        XmlElement elem = (XmlElement)elemRef.Target; 
                        if (elem != null 
                            && elem.IsConnected())
                            return elem; 
                    }
                }
            }
            return null; 
        }
 
        // Imports a node from another document to this document. 
        public virtual XmlNode ImportNode( XmlNode node, bool deep ) {
            return ImportNodeInternal( node, deep ); 
        }

        private XmlNode ImportNodeInternal( XmlNode node, bool deep ) {
            XmlNode newNode = null; 

            if ( node == null ) { 
                throw new InvalidOperationException(  Res.GetString(Res.Xdom_Import_NullNode) ); 
            }
            else { 
                switch ( node.NodeType ) {
                    case XmlNodeType.Element:
                        newNode = CreateElement( node.Prefix, node.LocalName, node.NamespaceURI );
                        ImportAttributes( node, newNode ); 
                        if ( deep )
                            ImportChildren( node, newNode, deep ); 
                        break; 

                    case XmlNodeType.Attribute: 
                        Debug.Assert( ((XmlAttribute)node).Specified );
                        newNode = CreateAttribute( node.Prefix, node.LocalName, node.NamespaceURI );
                        ImportChildren( node, newNode, true );
                        break; 

                    case XmlNodeType.Text: 
                        newNode = CreateTextNode( node.Value ); 
                        break;
                    case XmlNodeType.Comment: 
                        newNode = CreateComment( node.Value);
                        break;
                    case XmlNodeType.ProcessingInstruction:
                        newNode = CreateProcessingInstruction( node.Name, node.Value ); 
                        break;
                    case XmlNodeType.XmlDeclaration: 
                        XmlDeclaration decl = (XmlDeclaration) node; 
                        newNode = CreateXmlDeclaration( decl.Version, decl.Encoding, decl.Standalone );
                        break; 
                    case XmlNodeType.CDATA:
                        newNode = CreateCDataSection( node.Value );
                        break;
                    case XmlNodeType.DocumentType: 
                        XmlDocumentType docType = (XmlDocumentType)node;
                        newNode = CreateDocumentType( docType.Name, docType.PublicId, docType.SystemId, docType.InternalSubset ); 
                        break; 
                    case XmlNodeType.DocumentFragment:
                        newNode = CreateDocumentFragment(); 
                        if (deep)
                            ImportChildren( node, newNode, deep );
                        break;
 
                    case XmlNodeType.EntityReference:
                        newNode = CreateEntityReference( node.Name ); 
                        // we don't import the children of entity reference because they might result in different 
                        // children nodes given different namesapce context in the new document.
                        break; 

                    case XmlNodeType.Whitespace:
                        newNode = CreateWhitespace( node.Value );
                        break; 

                    case XmlNodeType.SignificantWhitespace: 
                        newNode = CreateSignificantWhitespace( node.Value ); 
                        break;
 
                    default:
                        throw new InvalidOperationException( String.Format( CultureInfo.InvariantCulture, Res.GetString(Res.Xdom_Import), node.NodeType.ToString() ) );
                }
            } 

            return newNode; 
        } 

        private void ImportAttributes( XmlNode fromElem, XmlNode toElem ) { 
            int cAttr = fromElem.Attributes.Count;
            for ( int iAttr = 0; iAttr < cAttr; iAttr++ ) {
                if ( fromElem.Attributes[iAttr].Specified )
                    toElem.Attributes.SetNamedItem( ImportNodeInternal( fromElem.Attributes[iAttr], true ) ); 
            }
        } 
 
        private void ImportChildren( XmlNode fromNode, XmlNode toNode, bool deep ) {
            Debug.Assert( toNode.NodeType != XmlNodeType.EntityReference ); 
            for ( XmlNode n = fromNode.FirstChild; n != null; n = n.NextSibling ) {
                toNode.AppendChild( ImportNodeInternal( n, deep ) );
            }
        } 

        // Microsoft extensions 
 
        // Gets the XmlNameTable associated with this
        // implementation. 
        public XmlNameTable NameTable
        {
            get { return implementation.NameTable; }
        } 

        // Creates a XmlAttribute with the specified Prefix, LocalName, 
        // and NamespaceURI. 
        public virtual XmlAttribute CreateAttribute( string prefix, string localName, string namespaceURI ) {
            return new XmlAttribute( AddAttrXmlName( prefix, localName, namespaceURI, null ), this ); 
        }

        protected internal virtual XmlAttribute CreateDefaultAttribute( string prefix, string localName, string namespaceURI ) {
            return new XmlUnspecifiedAttribute( prefix, localName, namespaceURI, this ); 
        }
 
        public virtual XmlElement CreateElement( string prefix, string localName, string namespaceURI) { 
            XmlElement elem = new XmlElement( AddXmlName( prefix, localName, namespaceURI, null ), true, this );
            if ( !IsLoading ) 
                AddDefaultAttributes( elem );
            return elem;
        }
 
        // Gets or sets a value indicating whether to preserve whitespace.
        public bool PreserveWhitespace { 
            get { return preserveWhitespace;} 
            set { preserveWhitespace = value;}
        } 

        // Gets a value indicating whether the node is read-only.
        public override bool IsReadOnly {
            get { return false;} 
        }
 
        internal XmlNamedNodeMap Entities { 
            get {
                if ( entities == null ) 
                    entities = new XmlNamedNodeMap( this );
                return entities;
            }
            set { entities = value; } 
        }
 
        internal bool IsLoading { 
            get { return isLoading;}
            set { isLoading = value; } 
        }

        internal bool ActualLoadingStatus{
            get { return actualLoadingStatus;} 
            set { actualLoadingStatus = value; }
        } 
 

        // Creates a XmlNode with the specified XmlNodeType, Prefix, Name, and NamespaceURI. 
        public virtual XmlNode CreateNode( XmlNodeType type, string prefix, string name, string namespaceURI ) {
            switch (type) {
                case XmlNodeType.Element:
                    if (prefix != null) 
                        return CreateElement( prefix, name, namespaceURI );
                    else 
                        return CreateElement( name, namespaceURI ); 

                case XmlNodeType.Attribute: 
                    if (prefix != null)
                        return CreateAttribute( prefix, name, namespaceURI );
                    else
                        return CreateAttribute( name, namespaceURI ); 

                case XmlNodeType.Text: 
                    return CreateTextNode( string.Empty ); 

                case XmlNodeType.CDATA: 
                    return CreateCDataSection( string.Empty );

                case XmlNodeType.EntityReference:
                    return CreateEntityReference( name ); 

                case XmlNodeType.ProcessingInstruction: 
                    return CreateProcessingInstruction( name, string.Empty ); 

                case XmlNodeType.XmlDeclaration: 
                    return CreateXmlDeclaration( "1.0", null, null );

                case XmlNodeType.Comment:
                    return CreateComment( string.Empty ); 

                case XmlNodeType.DocumentFragment: 
                    return CreateDocumentFragment(); 

                case XmlNodeType.DocumentType: 
                    return CreateDocumentType( name, string.Empty, string.Empty, string.Empty );

                case XmlNodeType.Document:
                    return new XmlDocument(); 

                case XmlNodeType.SignificantWhitespace: 
                    return CreateSignificantWhitespace( string.Empty ); 

                case XmlNodeType.Whitespace: 
                    return CreateWhitespace( string.Empty );

                default:
                    throw new ArgumentException( Res.GetString( Res.Arg_CannotCreateNode, type ) ); 
            }
        } 
 
        // Creates an XmlNode with the specified node type, Name, and
        // NamespaceURI. 
        public virtual XmlNode CreateNode( string nodeTypeString, string name, string namespaceURI ) {
            return CreateNode( ConvertToNodeType( nodeTypeString ), name, namespaceURI );
        }
 
        // Creates an XmlNode with the specified XmlNodeType, Name, and
        // NamespaceURI. 
        public virtual XmlNode CreateNode( XmlNodeType type, string name, string namespaceURI ) { 
            return CreateNode( type, null, name, namespaceURI );
        } 

        // Creates an XmlNode object based on the information in the XmlReader.
        // The reader must be positioned on a node or attribute.
        [PermissionSetAttribute( SecurityAction.InheritanceDemand, Name = "FullTrust" )] 
        public virtual XmlNode ReadNode( XmlReader reader ) {
            XmlNode node = null; 
            try { 
                IsLoading = true;
                XmlLoader loader = new XmlLoader(); 
                node = loader.ReadCurrentNode( this, reader );
            }
            finally {
                IsLoading = false; 
            }
            return node; 
        } 

        internal XmlNodeType ConvertToNodeType( string nodeTypeString ) { 
            if ( nodeTypeString == "element" ) {
                return XmlNodeType.Element;
            }
            else if ( nodeTypeString == "attribute" ) { 
                return XmlNodeType.Attribute;
            } 
            else if ( nodeTypeString == "text" ) { 
                return XmlNodeType.Text;
            } 
            else if ( nodeTypeString == "cdatasection" ) {
                return XmlNodeType.CDATA;
            }
            else if ( nodeTypeString == "entityreference" ) { 
                return XmlNodeType.EntityReference;
            } 
            else if ( nodeTypeString == "entity" ) { 
                return XmlNodeType.Entity;
            } 
            else if ( nodeTypeString == "processinginstruction" ) {
                return XmlNodeType.ProcessingInstruction;
            }
            else if ( nodeTypeString == "comment" ) { 
                return XmlNodeType.Comment;
            } 
            else if ( nodeTypeString == "document" ) { 
                return XmlNodeType.Document;
            } 
            else if ( nodeTypeString == "documenttype" ) {
                return XmlNodeType.DocumentType;
            }
            else if ( nodeTypeString == "documentfragment" ) { 
                return XmlNodeType.DocumentFragment;
            } 
            else if ( nodeTypeString == "notation" ) { 
                return XmlNodeType.Notation;
            } 
            else if ( nodeTypeString == "significantwhitespace" ) {
                return XmlNodeType.SignificantWhitespace;
            }
            else if ( nodeTypeString == "whitespace" ) { 
                return XmlNodeType.Whitespace;
            } 
            throw new ArgumentException( Res.GetString( Res.Xdom_Invalid_NT_String, nodeTypeString ) ); 
        }
 

        private XmlTextReader SetupReader( XmlTextReader tr ) {
            tr.XmlValidatingReaderCompatibilityMode = true;
            tr.EntityHandling = EntityHandling.ExpandCharEntities; 
            if ( this.HasSetResolver )
                tr.XmlResolver = GetResolver(); 
            return tr; 
        }
 
        // Loads the XML document from the specified URL.
        [ResourceConsumption(ResourceScope.Machine)]
        [ResourceExposure(ResourceScope.Machine)]
        public virtual void Load( string filename ) { 
            XmlTextReader reader = SetupReader( new XmlTextReader( filename, NameTable ) );
            try { 
                Load( reader ); 
            }
            finally { 
                reader.Close();
            }
        }
 
        public virtual void Load( Stream inStream ) {
            XmlTextReader reader = SetupReader( new XmlTextReader( inStream, NameTable ) ); 
            try { 
                Load( reader );
            } 
            finally {
                reader.Impl.Close( false );
            }
        } 

        // Loads the XML document from the specified TextReader. 
        public virtual void Load( TextReader txtReader ) { 
            XmlTextReader reader = SetupReader( new XmlTextReader( txtReader, NameTable ) );
            try { 
                Load( reader );
            }
            finally {
                reader.Impl.Close( false ); 
            }
        } 
 
        // Loads the XML document from the specified XmlReader.
        public virtual void Load( XmlReader reader ) { 
            try {
                IsLoading = true;
                actualLoadingStatus = true;
                RemoveAll(); 
                fEntRefNodesPresent = false;
                fCDataNodesPresent  = false; 
                reportValidity = true; 

                XmlLoader loader = new XmlLoader(); 
                loader.Load( this, reader, preserveWhitespace );
            }
            finally {
                IsLoading = false; 
                actualLoadingStatus = false;
 
                // Ensure the bit is still on after loading a dtd 
                reportValidity = true;
            } 
        }

        // Loads the XML document from the specified string.
        public virtual void LoadXml( string xml ) { 
            XmlTextReader reader = SetupReader( new XmlTextReader( new StringReader( xml ), NameTable ));
            try { 
                Load( reader ); 
            }
            finally { 
                reader.Close();
            }
        }
 
        //TextEncoding is the one from XmlDeclaration if there is any
        internal Encoding TextEncoding { 
            get { 
                if ( Declaration != null )
                { 
                    string value = Declaration.Encoding;
                    if ( value.Length > 0 ) {
                        return System.Text.Encoding.GetEncoding( value );
                    } 
                }
                return null; 
            } 
        }
 
        public override string InnerText {
            set {
                throw new InvalidOperationException(Res.GetString(Res.Xdom_Document_Innertext));
            } 
        }
 
        public override string InnerXml { 
            get {
                return base.InnerXml; 
            }
            set {
                LoadXml( value );
            } 
        }
 
        // Saves the XML document to the specified file. 
        //Saves out the to the file with exact content in the XmlDocument.
        [ResourceConsumption(ResourceScope.Machine)] 
        [ResourceExposure(ResourceScope.Machine)]
        public virtual void Save( string filename ) {
            if ( DocumentElement == null )
                throw new XmlException( Res.Xml_InvalidXmlDocument, Res.GetString( Res.Xdom_NoRootEle ) ); 
            XmlDOMTextWriter xw = new XmlDOMTextWriter( filename, TextEncoding );
            try { 
                if ( preserveWhitespace == false ) 
                    xw.Formatting = Formatting.Indented;
                 WriteTo( xw ); 
                 xw.Flush();
            }
            finally {
                xw.Close(); 
            }
        } 
 
        //Saves out the to the file with exact content in the XmlDocument.
        public virtual void Save( Stream outStream ) { 
            XmlDOMTextWriter xw = new XmlDOMTextWriter( outStream, TextEncoding );
            if ( preserveWhitespace == false )
                xw.Formatting = Formatting.Indented;
            WriteTo( xw ); 
            xw.Flush();
        } 
 
        // Saves the XML document to the specified TextWriter.
        // 
        //Saves out the file with xmldeclaration which has encoding value equal to
        //that of textwriter's encoding
        public virtual void Save( TextWriter writer ) {
            XmlDOMTextWriter xw = new XmlDOMTextWriter( writer ); 
            if ( preserveWhitespace == false )
                    xw.Formatting = Formatting.Indented; 
            Save( xw ); 
        }
 
        // Saves the XML document to the specified XmlWriter.
        //
        //Saves out the file with xmldeclaration which has encoding value equal to
        //that of textwriter's encoding 
        public virtual void Save( XmlWriter w ) {
            XmlNode n = this.FirstChild; 
            if( n == null ) 
                return;
            if( w.WriteState == WriteState.Start ) { 
                if( n is XmlDeclaration ) {
                    if( Standalone.Length == 0 )
                        w.WriteStartDocument();
                    else if( Standalone == "yes" ) 
                        w.WriteStartDocument( true );
                    else if( Standalone == "no" ) 
                        w.WriteStartDocument( false ); 
                    n = n.NextSibling;
                } 
                else {
                    w.WriteStartDocument();
                }
            } 
            while( n != null ) {
                //Debug.Assert( n.NodeType != XmlNodeType.XmlDeclaration ); 
                n.WriteTo( w ); 
                n = n.NextSibling;
            } 
            w.Flush();
        }

        // Saves the node to the specified XmlWriter. 
        //
        //Writes out the to the file with exact content in the XmlDocument. 
        public override void WriteTo( XmlWriter w ) { 
            WriteContentTo( w );
        } 

        // Saves all the children of the node to the specified XmlWriter.
        //
        //Writes out the to the file with exact content in the XmlDocument. 
        public override void WriteContentTo( XmlWriter xw ) {
            foreach( XmlNode n in this ) { 
                n.WriteTo( xw ); 
            }
        } 

        public void Validate(ValidationEventHandler validationEventHandler) {
            Validate(validationEventHandler, this);
        } 

        public void Validate(ValidationEventHandler validationEventHandler, XmlNode nodeToValidate) { 
            if (this.schemas == null || this.schemas.Count == 0) { //Should we error 
                throw new InvalidOperationException(Res.GetString(Res.XmlDocument_NoSchemaInfo));
            } 
            XmlDocument parentDocument = nodeToValidate.Document;
            if (parentDocument != this) {
                throw new ArgumentException(Res.GetString(Res.XmlDocument_NodeNotFromDocument, "nodeToValidate"));
            } 
            if (nodeToValidate == this) {
                reportValidity = false; 
            } 
            DocumentSchemaValidator validator = new DocumentSchemaValidator(this, schemas, validationEventHandler);
            validator.Validate(nodeToValidate); 
            if (nodeToValidate == this) {
                reportValidity = true;
            }
        } 

        public event XmlNodeChangedEventHandler NodeInserting { 
            add { 
                onNodeInsertingDelegate += value;
            } 
            remove {
                onNodeInsertingDelegate -= value;
            }
        } 

        public event XmlNodeChangedEventHandler NodeInserted { 
            add { 
                onNodeInsertedDelegate += value;
            } 
            remove {
                onNodeInsertedDelegate -= value;
            }
        } 

        public event XmlNodeChangedEventHandler NodeRemoving { 
            add { 
                onNodeRemovingDelegate += value;
            } 
            remove {
                onNodeRemovingDelegate -= value;
            }
        } 

        public event XmlNodeChangedEventHandler NodeRemoved { 
            add { 
                onNodeRemovedDelegate += value;
            } 
            remove {
                onNodeRemovedDelegate -= value;
            }
        } 

        public event XmlNodeChangedEventHandler NodeChanging { 
            add { 
                onNodeChangingDelegate += value;
            } 
            remove {
                onNodeChangingDelegate -= value;
            }
        } 

        public event XmlNodeChangedEventHandler NodeChanged { 
            add { 
                onNodeChangedDelegate += value;
            } 
            remove {
                onNodeChangedDelegate -= value;
            }
        } 

        internal override XmlNodeChangedEventArgs GetEventArgs(XmlNode node, XmlNode oldParent, XmlNode newParent, string oldValue, string newValue, XmlNodeChangedAction action) { 
            reportValidity = false; 

            switch (action) { 
                case XmlNodeChangedAction.Insert:
                    if (onNodeInsertingDelegate == null && onNodeInsertedDelegate == null) {
                        return null;
                    } 
                    break;
                case XmlNodeChangedAction.Remove: 
                    if (onNodeRemovingDelegate == null && onNodeRemovedDelegate == null) { 
                        return null;
                    } 
                    break;
                case XmlNodeChangedAction.Change:
                    if (onNodeChangingDelegate == null && onNodeChangedDelegate == null) {
                        return null; 
                    }
                    break; 
            } 
            return new XmlNodeChangedEventArgs( node, oldParent, newParent, oldValue, newValue, action );
        } 

        internal XmlNodeChangedEventArgs GetInsertEventArgsForLoad( XmlNode node, XmlNode newParent ) {
            if (onNodeInsertingDelegate == null && onNodeInsertedDelegate == null) {
                return null; 
            }
            string nodeValue = node.Value; 
            return new XmlNodeChangedEventArgs(node, null, newParent, nodeValue, nodeValue, XmlNodeChangedAction.Insert); 
        }
 
        internal override void BeforeEvent( XmlNodeChangedEventArgs args ) {
            if ( args != null ) {
                switch ( args.Action ) {
                    case XmlNodeChangedAction.Insert: 
                        if ( onNodeInsertingDelegate != null )
                            onNodeInsertingDelegate( this, args ); 
                        break; 

                    case XmlNodeChangedAction.Remove: 
                        if ( onNodeRemovingDelegate != null )
                            onNodeRemovingDelegate( this, args );
                        break;
 
                    case XmlNodeChangedAction.Change:
                        if ( onNodeChangingDelegate != null ) 
                            onNodeChangingDelegate( this, args ); 
                        break;
                } 
            }
        }

        internal override void AfterEvent( XmlNodeChangedEventArgs args ) { 
            if ( args != null ) {
                switch ( args.Action ) { 
                    case XmlNodeChangedAction.Insert: 
                        if ( onNodeInsertedDelegate != null )
                            onNodeInsertedDelegate( this, args ); 
                        break;

                    case XmlNodeChangedAction.Remove:
                        if ( onNodeRemovedDelegate != null ) 
                            onNodeRemovedDelegate( this, args );
                        break; 
 
                    case XmlNodeChangedAction.Change:
                        if ( onNodeChangedDelegate != null ) 
                            onNodeChangedDelegate( this, args );
                        break;
                }
            } 
        }
 
        // The function such through schema info to find out if there exists a default attribute with passed in names in the passed in element 
        // If so, return the newly created default attribute (with children tree);
        // Otherwise, return null. 

        internal XmlAttribute GetDefaultAttribute( XmlElement elem, string attrPrefix, string attrLocalname, string attrNamespaceURI ) {
            SchemaInfo schInfo = DtdSchemaInfo;
            SchemaElementDecl ed = GetSchemaElementDecl( elem ); 
            if ( ed != null && ed.AttDefs != null ) {
                IDictionaryEnumerator attrDefs = ed.AttDefs.GetEnumerator(); 
                while ( attrDefs.MoveNext() ) { 
                    SchemaAttDef attdef = (SchemaAttDef)attrDefs.Value;
                    if ( attdef.Presence == SchemaDeclBase.Use.Default || 
                        attdef.Presence == SchemaDeclBase.Use.Fixed ) {
                        if ( attdef.Name.Name == attrLocalname ) {
                            if ( ( schInfo.SchemaType == SchemaType.DTD && attdef.Name.Namespace == attrPrefix ) ||
                                 ( schInfo.SchemaType != SchemaType.DTD && attdef.Name.Namespace == attrNamespaceURI ) ) { 
                                 //find a def attribute with the same name, build a default attribute and return
                                 XmlAttribute defattr = PrepareDefaultAttribute( attdef, attrPrefix, attrLocalname, attrNamespaceURI ); 
                                 return defattr; 
                            }
                        } 
                    }
                }
            }
            return null; 
        }
 
        internal String Version { 
            get {
                XmlDeclaration decl = Declaration; 
                if ( decl != null )
                    return decl.Version;
                return null;
            } 
        }
 
        internal String Encoding { 
            get {
                XmlDeclaration decl = Declaration; 
                if ( decl != null )
                    return decl.Encoding;
                return null;
            } 
        }
 
        internal String Standalone { 
            get {
                XmlDeclaration decl = Declaration; 
                if ( decl != null )
                    return decl.Standalone;
                return null;
            } 
        }
 
        internal XmlEntity GetEntityNode( String name ) { 
            if ( DocumentType != null ) {
                XmlNamedNodeMap entites = DocumentType.Entities; 
                if ( entites != null )
                    return (XmlEntity)(entites.GetNamedItem( name ));
            }
            return null; 
        }
 
        public override IXmlSchemaInfo SchemaInfo { 
            get {
                if (reportValidity) { 
                    XmlElement documentElement = DocumentElement;
                    if (documentElement != null) {
                        switch (documentElement.SchemaInfo.Validity) {
                            case XmlSchemaValidity.Valid: 
                                return ValidSchemaInfo;
                            case XmlSchemaValidity.Invalid: 
                                return InvalidSchemaInfo; 
                        }
                    } 
                }
                return NotKnownSchemaInfo;
            }
        } 

        public override String BaseURI { 
            get { return baseURI; } 
        }
 
        internal void SetBaseURI( String inBaseURI ) {
            baseURI = inBaseURI;
        }
 
        internal override XmlNode AppendChildForLoad( XmlNode newChild, XmlDocument doc ) {
            Debug.Assert( doc == this ); 
 
            if ( !IsValidChildType( newChild.NodeType ))
                throw new InvalidOperationException( Res.GetString(Res.Xdom_Node_Insert_TypeConflict) ); 

            if ( !CanInsertAfter( newChild, LastChild ) )
                throw new InvalidOperationException( Res.GetString(Res.Xdom_Node_Insert_Location) );
 
            XmlNodeChangedEventArgs args = GetInsertEventArgsForLoad( newChild, this );
 
            if ( args != null ) 
                BeforeEvent( args );
 
            XmlLinkedNode newNode = (XmlLinkedNode) newChild;

            if ( lastChild == null ) {
                newNode.next = newNode; 
            }
            else { 
                newNode.next = lastChild.next; 
                lastChild.next = newNode;
            } 

            lastChild = newNode;
            newNode.SetParentForLoad( this );
 
            if ( args != null )
                AfterEvent( args ); 
 
            return newNode;
        } 

        internal override XPathNodeType XPNodeType { get { return XPathNodeType.Root; } }

        internal bool HasEntityReferences { 
            get {
                return fEntRefNodesPresent; 
            } 
        }
 
        internal XmlAttribute NamespaceXml {
            get {
                if (namespaceXml == null) {
                    namespaceXml = new XmlAttribute(AddAttrXmlName(strXmlns, strXml, strReservedXmlns, null), this); 
                    namespaceXml.Value = strReservedXml;
                } 
                return namespaceXml; 
            }
        } 
    }
}

// File provided for Reference Use Only by Microsoft Corporation (c) 2007.
//------------------------------------------------------------------------------ 
// 
//     Copyright (c) Microsoft Corporation.  All rights reserved.
// 
// [....] 
//-----------------------------------------------------------------------------
 
namespace System.Xml 
{
    using System; 
    using System.Collections;
    using System.Diagnostics;
    using System.IO;
    using System.Text; 
    using System.Xml.Schema;
    using System.Xml.XPath; 
    using System.Security; 
    using System.Security.Permissions;
    using System.Globalization; 
    using System.Runtime.Versioning;

    // Represents an entire document. An XmlDocument contains XML data.
    public class XmlDocument: XmlNode { 
        private XmlImplementation implementation;
        private DomNameTable domNameTable; // hash table of XmlName 
        private XmlLinkedNode lastChild; 
        private XmlNamedNodeMap entities;
        private Hashtable htElementIdMap; 
        private Hashtable htElementIDAttrDecl; //key: id; object: the ArrayList of the elements that have the same id (connected or disconnected)
        private SchemaInfo schemaInfo;
        private XmlSchemaSet schemas; // schemas associated with the cache
        private bool reportValidity; 
        //This variable represents the actual loading status. Since, IsLoading will
        //be manipulated soemtimes for adding content to EntityReference this variable 
        //has been added which would always represent the loading status of document. 
        private bool actualLoadingStatus;
 
        private XmlNodeChangedEventHandler onNodeInsertingDelegate;
        private XmlNodeChangedEventHandler onNodeInsertedDelegate;
        private XmlNodeChangedEventHandler onNodeRemovingDelegate;
        private XmlNodeChangedEventHandler onNodeRemovedDelegate; 
        private XmlNodeChangedEventHandler onNodeChangingDelegate;
        private XmlNodeChangedEventHandler onNodeChangedDelegate; 
 
        // false if there are no ent-ref present, true if ent-ref nodes are or were present (i.e. if all ent-ref were removed, the doc will not clear this flag)
        internal bool fEntRefNodesPresent; 
        internal bool fCDataNodesPresent;

        private bool preserveWhitespace;
        private bool isLoading; 

        // special name strings for 
        internal string strDocumentName; 
        internal string strDocumentFragmentName;
        internal string strCommentName; 
        internal string strTextName;
        internal string strCDataSectionName;
        internal string strEntityName;
        internal string strID; 
        internal string strXmlns;
        internal string strXml; 
        internal string strSpace; 
        internal string strLang;
        internal string strEmpty; 

        internal string strNonSignificantWhitespaceName;
        internal string strSignificantWhitespaceName;
        internal string strReservedXmlns; 
        internal string strReservedXml;
 
        internal String baseURI; 

        private XmlResolver resolver; 
        internal bool       bSetResolver;
        internal object     objLock;

        private XmlAttribute namespaceXml; 

        static internal EmptyEnumerator EmptyEnumerator = new EmptyEnumerator(); 
        static internal IXmlSchemaInfo NotKnownSchemaInfo = new XmlSchemaInfo(XmlSchemaValidity.NotKnown); 
        static internal IXmlSchemaInfo ValidSchemaInfo = new XmlSchemaInfo(XmlSchemaValidity.Valid);
        static internal IXmlSchemaInfo InvalidSchemaInfo = new XmlSchemaInfo(XmlSchemaValidity.Invalid); 

        // Initializes a new instance of the XmlDocument class.
        public XmlDocument(): this( new XmlImplementation() ) {
        } 

        // Initializes a new instance 
        // of the XmlDocument class with the specified XmlNameTable. 
        public XmlDocument( XmlNameTable nt ) : this( new XmlImplementation( nt ) ) {
        } 

        protected internal XmlDocument( XmlImplementation imp ): base() {

            implementation = imp; 
            domNameTable = new DomNameTable( this );
 
            // force the following string instances to be default in the nametable 
            XmlNameTable nt = this.NameTable;
            nt.Add( string.Empty ); 
            strDocumentName = nt.Add( "#document" );
            strDocumentFragmentName  = nt.Add( "#document-fragment" );
            strCommentName = nt.Add( "#comment" );
            strTextName = nt.Add( "#text" ); 
            strCDataSectionName = nt.Add( "#cdata-section" );
            strEntityName = nt.Add( "#entity" ); 
            strID = nt.Add( "id" ); 
            strNonSignificantWhitespaceName = nt.Add( "#whitespace" );
            strSignificantWhitespaceName = nt.Add( "#significant-whitespace" ); 
            strXmlns = nt.Add( "xmlns" );
            strXml = nt.Add(  "xml" );
            strSpace = nt.Add(  "space" );
            strLang = nt.Add(  "lang" ); 
            strReservedXmlns = nt.Add( XmlReservedNs.NsXmlNs );
            strReservedXml = nt.Add( XmlReservedNs.NsXml ); 
            strEmpty = nt.Add( String.Empty ); 
            baseURI = String.Empty;
 
            objLock = new object();
        }

        internal SchemaInfo DtdSchemaInfo { 
            get { return schemaInfo; }
            set { schemaInfo = value; } 
        } 

        // NOTE: This does not correctly check start name char, but we cannot change it since it would be a breaking change. 
        internal static void CheckName( String name ) {
            int endPos = ValidateNames.ParseNmtoken( name, 0 );
            if (endPos < name.Length) {
                throw new XmlException(Res.Xml_BadNameChar, XmlException.BuildCharExceptionArgs(name, endPos)); 
            }
        } 
 
        internal XmlName AddXmlName(string prefix, string localName, string namespaceURI, IXmlSchemaInfo schemaInfo) {
            XmlName n = domNameTable.AddName(prefix, localName, namespaceURI, schemaInfo); 
            Debug.Assert( (prefix == null) ? (n.Prefix.Length == 0) : (prefix == n.Prefix) );
            Debug.Assert( n.LocalName == localName );
            Debug.Assert( (namespaceURI == null) ? (n.NamespaceURI.Length == 0) : (n.NamespaceURI == namespaceURI) );
            return n; 
        }
 
        internal XmlName GetXmlName(string prefix, string localName, string namespaceURI, IXmlSchemaInfo schemaInfo) { 
            XmlName n = domNameTable.GetName(prefix, localName, namespaceURI, schemaInfo);
            Debug.Assert(n == null || ((prefix == null) ? (n.Prefix.Length == 0) : (prefix == n.Prefix))); 
            Debug.Assert(n == null || n.LocalName == localName);
            Debug.Assert(n == null || ((namespaceURI == null) ? (n.NamespaceURI.Length == 0) : (n.NamespaceURI == namespaceURI)));
            return n;
        } 

        internal XmlName AddAttrXmlName(string prefix, string localName, string namespaceURI, IXmlSchemaInfo schemaInfo) { 
            XmlName xmlName = AddXmlName(prefix, localName, namespaceURI, schemaInfo); 
            Debug.Assert( (prefix == null) ? (xmlName.Prefix.Length == 0) : (prefix == xmlName.Prefix) );
            Debug.Assert( xmlName.LocalName == localName ); 
            Debug.Assert( (namespaceURI == null) ? (xmlName.NamespaceURI.Length == 0) : (xmlName.NamespaceURI == namespaceURI) );

            if ( !this.IsLoading ) {
                // Use atomized versions instead of prefix, localName and nsURI 
                object oPrefix       = xmlName.Prefix;
                object oNamespaceURI = xmlName.NamespaceURI; 
                object oLocalName    = xmlName.LocalName; 
                if ( ( oPrefix == (object)strXmlns || ( oPrefix == (object)strEmpty && oLocalName == (object)strXmlns ) ) ^ ( oNamespaceURI == (object)strReservedXmlns ) )
                    throw new ArgumentException( Res.GetString( Res.Xdom_Attr_Reserved_XmlNS, namespaceURI ) ); 
            }
            return xmlName;
        }
 
        internal bool AddIdInfo( XmlName eleName, XmlName attrName ) {
            //when XmlLoader call XmlDocument.AddInfo, the element.XmlName and attr.XmlName 
            //have already been replaced with the ones that don't have namespace values (or just 
            //string.Empty) because in DTD, the namespace is not supported
            if ( htElementIDAttrDecl == null || htElementIDAttrDecl[eleName] == null ) { 
                if ( htElementIDAttrDecl == null )
                    htElementIDAttrDecl = new Hashtable();
                htElementIDAttrDecl.Add(eleName, attrName);
                return true; 
            }
            return false; 
        } 

        private XmlName GetIDInfoByElement_(XmlName eleName) 
        {
            //When XmlDocument is getting the IDAttribute for a given element,
            //we need only compare the prefix and localname of element.XmlName with
            //the registered htElementIDAttrDecl. 
            XmlName newName = GetXmlName(eleName.Prefix, eleName.LocalName, string.Empty, null);
            if (newName != null) { 
                return (XmlName)(htElementIDAttrDecl[newName]); 
            }
            return null; 
        }

        internal XmlName GetIDInfoByElement( XmlName eleName ) {
            if (htElementIDAttrDecl == null) 
                return null;
            else 
                return GetIDInfoByElement_(eleName); 
        }
 
        private WeakReference GetElement(ArrayList elementList, XmlElement elem) {
            ArrayList gcElemRefs = new ArrayList();
            foreach( WeakReference elemRef in elementList) {
                if ( !elemRef.IsAlive) 
                    //take notes on the garbage collected nodes
                    gcElemRefs.Add(elemRef); 
                else { 
                    if ((XmlElement)(elemRef.Target) == elem)
                        return elemRef; 
                }
            }
            //Clear out the gced elements
            foreach( WeakReference elemRef in gcElemRefs) 
                elementList.Remove(elemRef);
            return null; 
        } 

        internal void AddElementWithId( string id, XmlElement elem ) { 
            if (htElementIdMap == null || !htElementIdMap.Contains(id)) {
                if ( htElementIdMap == null )
                    htElementIdMap = new Hashtable();
                ArrayList elementList = new ArrayList(); 
                elementList.Add(new WeakReference(elem));
                htElementIdMap.Add(id, elementList); 
            } 
            else {
                // there are other element(s) that has the same id 
                ArrayList elementList = (ArrayList)(htElementIdMap[id]);
                if (GetElement(elementList, elem) == null)
                    elementList.Add(new WeakReference(elem));
            } 
        }
 
        internal void RemoveElementWithId( string id, XmlElement elem ) { 
            if (htElementIdMap != null && htElementIdMap.Contains(id)) {
                ArrayList elementList = (ArrayList)(htElementIdMap[id]); 
                WeakReference elemRef = GetElement(elementList, elem);
                if (elemRef != null) {
                    elementList.Remove(elemRef);
                    if (elementList.Count == 0) 
                        htElementIdMap.Remove(id);
                } 
            } 
        }
 

        // Creates a duplicate of this node.
        public override XmlNode CloneNode( bool deep ) {
            XmlDocument clone = Implementation.CreateDocument(); 
            clone.SetBaseURI(this.baseURI);
            if (deep) 
                clone.ImportChildren( this, clone, deep ); 

            return clone; 
        }

        // Gets the type of the current node.
        public override XmlNodeType NodeType { 
            get { return XmlNodeType.Document; }
        } 
 
        public override XmlNode ParentNode {
            get { return null; } 
        }

        // Gets the node for the DOCTYPE declaration.
        public virtual XmlDocumentType DocumentType { 
            get { return(XmlDocumentType) FindChild( XmlNodeType.DocumentType ); }
        } 
 
        internal virtual XmlDeclaration Declaration {
            get { 
                if ( HasChildNodes ) {
                    XmlDeclaration dec = FirstChild as XmlDeclaration;
                    return dec;
                } 
                return null;
            } 
        } 

        // Gets the XmlImplementation object for this document. 
        public XmlImplementation Implementation {
            get { return this.implementation; }
        }
 
        // Gets the name of the node.
        public override String Name  { 
            get { return strDocumentName; } 
        }
 
        // Gets the name of the current node without the namespace prefix.
        public override String LocalName {
            get { return strDocumentName; }
        } 

        // Gets the root XmlElement for the document. 
        public XmlElement DocumentElement { 
            get { return(XmlElement)FindChild(XmlNodeType.Element); }
        } 

        internal override bool IsContainer {
            get { return true; }
        } 

        internal override XmlLinkedNode LastNode 
        { 
            get { return lastChild; }
            set { lastChild = value; } 
        }

        // Gets the XmlDocument that contains this node.
        public override XmlDocument OwnerDocument 
        {
            get { return null; } 
        } 

        public XmlSchemaSet Schemas { 
            get {
                if (schemas == null) {
                    schemas = new XmlSchemaSet(NameTable);
                } 
                return schemas;
            } 
 
            set {
                schemas = value; 
            }
        }

        internal bool CanReportValidity { 
            get { return reportValidity; }
        } 
 
        internal bool HasSetResolver {
            get { return bSetResolver; } 
        }

        internal XmlResolver GetResolver() {
           return resolver; 
        }
 
        public virtual XmlResolver XmlResolver { 
            set {
                if ( value != null ) { 
                    try {
                        new NamedPermissionSet( "FullTrust" ).Demand();
                    }
                    catch ( SecurityException e ) { 
                        throw new SecurityException( Res.GetString( Res.Xml_UntrustedCodeSettingResolver ), e );
                    } 
                } 

                resolver = value; 
                if ( !bSetResolver )
                    bSetResolver = true;

                XmlDocumentType dtd = this.DocumentType; 
                if ( dtd != null ) {
                    dtd.DtdSchemaInfo = null; 
                } 
            }
        } 
        internal override bool IsValidChildType( XmlNodeType type ) {
            switch ( type ) {
                case XmlNodeType.ProcessingInstruction:
                case XmlNodeType.Comment: 
                case XmlNodeType.Whitespace:
                case XmlNodeType.SignificantWhitespace: 
                    return true; 

                case XmlNodeType.DocumentType: 
                    if ( DocumentType != null )
                        throw new InvalidOperationException( Res.GetString(Res.Xdom_DualDocumentTypeNode) );
                    return true;
 
                case XmlNodeType.Element:
                    if ( DocumentElement != null ) 
                        throw new InvalidOperationException( Res.GetString(Res.Xdom_DualDocumentElementNode) ); 
                    return true;
 
                case XmlNodeType.XmlDeclaration:
                    if ( Declaration != null )
                        throw new InvalidOperationException( Res.GetString(Res.Xdom_DualDeclarationNode) );
                    return true; 

                default: 
                    return false; 
            }
        } 
        // the function examines all the siblings before the refNode
        //  if any of the nodes has type equals to "nt", return true; otherwise, return false;
        private bool HasNodeTypeInPrevSiblings( XmlNodeType nt, XmlNode refNode ) {
            if ( refNode == null ) 
                return false;
 
            XmlNode node = null; 
            if ( refNode.ParentNode != null )
                node = refNode.ParentNode.FirstChild; 
            while ( node != null ) {
                if ( node.NodeType == nt )
                    return true;
                if ( node == refNode ) 
                    break;
                node = node.NextSibling; 
            } 
            return false;
        } 

        // the function examines all the siblings after the refNode
        //  if any of the nodes has the type equals to "nt", return true; otherwise, return false;
        private bool HasNodeTypeInNextSiblings( XmlNodeType nt, XmlNode refNode ) { 
            XmlNode node = refNode;
            while ( node != null ) { 
                if ( node.NodeType == nt ) 
                    return true;
                node = node.NextSibling; 
            }
            return false;
        }
 
        internal override bool CanInsertBefore( XmlNode newChild, XmlNode refChild ) {
            if ( refChild == null ) 
                refChild = FirstChild; 

            if ( refChild == null ) 
                return true;

            switch ( newChild.NodeType ) {
                case XmlNodeType.XmlDeclaration: 
                    return ( refChild == FirstChild );
 
                case XmlNodeType.ProcessingInstruction: 
                case XmlNodeType.Comment:
                    return refChild.NodeType != XmlNodeType.XmlDeclaration; 

                case XmlNodeType.DocumentType: {
                    if ( refChild.NodeType != XmlNodeType.XmlDeclaration ) {
                        //if refChild is not the XmlDeclaration node, only need to go through the sibling before and including refChild to 
                        //  make sure no Element ( rootElem node ) before the current position
                        return !HasNodeTypeInPrevSiblings( XmlNodeType.Element, refChild.PreviousSibling ); 
                    } 
                }
                break; 

                case XmlNodeType.Element: {
                    if ( refChild.NodeType != XmlNodeType.XmlDeclaration ) {
                        //if refChild is not the XmlDeclaration node, only need to go through the siblings after and including the refChild to 
                        //  make sure no DocType node and XmlDeclaration node after the current posistion.
                        return !HasNodeTypeInNextSiblings( XmlNodeType.DocumentType, refChild ); 
                    } 
                }
                break; 
            }

            return false;
        } 

        internal override bool CanInsertAfter( XmlNode newChild, XmlNode refChild ) { 
            if ( refChild == null ) 
                refChild = LastChild;
 
            if ( refChild == null )
                return true;

            switch ( newChild.NodeType ) { 
                case XmlNodeType.ProcessingInstruction:
                case XmlNodeType.Comment: 
                case XmlNodeType.Whitespace: 
                case XmlNodeType.SignificantWhitespace:
                    return true; 

                case XmlNodeType.DocumentType: {
                    //we will have to go through all the siblings before the refChild just to make sure no Element node ( rootElem )
                    //  before the current position 
                    return !HasNodeTypeInPrevSiblings( XmlNodeType.Element, refChild );
                } 
 
                case XmlNodeType.Element: {
                    return !HasNodeTypeInNextSiblings( XmlNodeType.DocumentType, refChild.NextSibling ); 
                }

            }
 
            return false;
        } 
 
        // Creates an XmlAttribute with the specified name.
        public XmlAttribute CreateAttribute( String name ) { 
            String prefix = String.Empty;
            String localName = String.Empty;
            String namespaceURI = String.Empty;
 
            SplitName( name, out prefix, out localName );
 
            SetDefaultNamespace( prefix, localName, ref namespaceURI ); 

            return CreateAttribute( prefix, localName, namespaceURI ); 
        }

        internal void SetDefaultNamespace( String prefix, String localName, ref String namespaceURI ) {
            if ( prefix == strXmlns || ( prefix.Length == 0 && localName == strXmlns ) ) { 
                namespaceURI = strReservedXmlns;
            } else if ( prefix == strXml ) { 
                namespaceURI = strReservedXml; 
            }
        } 

        // Creates a XmlCDataSection containing the specified data.
        public virtual XmlCDataSection CreateCDataSection( String data ) {
            fCDataNodesPresent = true; 
            return new XmlCDataSection( data, this );
        } 
 
        // Creates an XmlComment containing the specified data.
        public virtual XmlComment CreateComment( String data ) { 
            return new XmlComment( data, this );
        }

        // Returns a new XmlDocumentType object. 
        [PermissionSetAttribute( SecurityAction.InheritanceDemand, Name = "FullTrust" )]
        public virtual XmlDocumentType CreateDocumentType( string name, string publicId, string systemId, string internalSubset ) { 
            return new XmlDocumentType( name, publicId, systemId, internalSubset, this ); 
        }
 
        // Creates an XmlDocumentFragment.
        public virtual XmlDocumentFragment CreateDocumentFragment() {
            return new XmlDocumentFragment( this );
        } 

        // Creates an element with the specified name. 
        public XmlElement CreateElement( String name ) { 
            string prefix = String.Empty;
            string localName = String.Empty; 
            SplitName( name, out prefix, out localName );
            return CreateElement( prefix, localName, string.Empty );
        }
 

        internal void AddDefaultAttributes( XmlElement elem ) { 
            SchemaInfo schInfo = DtdSchemaInfo; 
            SchemaElementDecl ed = GetSchemaElementDecl( elem );
            if ( ed != null && ed.AttDefs != null ) { 
                IDictionaryEnumerator attrDefs = ed.AttDefs.GetEnumerator();
                while ( attrDefs.MoveNext() ) {
                    SchemaAttDef attdef = (SchemaAttDef)attrDefs.Value;
                    if ( attdef.Presence == SchemaDeclBase.Use.Default || 
                         attdef.Presence == SchemaDeclBase.Use.Fixed ) {
                         //build a default attribute and return 
                         string attrPrefix = string.Empty; 
                         string attrLocalname = attdef.Name.Name;
                         string attrNamespaceURI = string.Empty; 
                         if ( schInfo.SchemaType == SchemaType.DTD )
                            attrPrefix = attdef.Name.Namespace;
                         else {
                            attrPrefix = attdef.Prefix; 
                            attrNamespaceURI = attdef.Name.Namespace;
                         } 
                         XmlAttribute defattr = PrepareDefaultAttribute( attdef, attrPrefix, attrLocalname, attrNamespaceURI ); 
                         elem.SetAttributeNode( defattr );
                    } 
                }
            }
        }
 
        private SchemaElementDecl GetSchemaElementDecl( XmlElement elem ) {
            SchemaInfo schInfo = DtdSchemaInfo; 
            if ( schInfo != null ) { 
                //build XmlQualifiedName used to identify the element schema declaration
                XmlQualifiedName   qname = new XmlQualifiedName( elem.LocalName, schInfo.SchemaType == SchemaType.DTD ? elem.Prefix : elem.NamespaceURI ); 
                //get the schema info for the element
                SchemaElementDecl elemDecl;
                if ( schInfo.ElementDecls.TryGetValue(qname, out elemDecl) ) {
                    return elemDecl; 
                }
            } 
            return null; 
        }
 
        //Will be used by AddDeafulatAttributes() and GetDefaultAttribute() methods
        private XmlAttribute PrepareDefaultAttribute( SchemaAttDef attdef, string attrPrefix, string attrLocalname, string attrNamespaceURI ) {
            SetDefaultNamespace( attrPrefix, attrLocalname, ref attrNamespaceURI );
            XmlAttribute defattr = CreateDefaultAttribute( attrPrefix, attrLocalname, attrNamespaceURI ); 
            //parsing the default value for the default attribute
            defattr.InnerXml = attdef.DefaultValueRaw; 
            //during the expansion of the tree, the flag could be set to true, we need to set it back. 
            XmlUnspecifiedAttribute unspAttr = defattr as XmlUnspecifiedAttribute;
            if ( unspAttr != null ) { 
                unspAttr.SetSpecified( false );
            }
            return defattr;
        } 

        // Creates an XmlEntityReference with the specified name. 
        public virtual XmlEntityReference CreateEntityReference( String name ) { 
            return new XmlEntityReference( name, this );
        } 

        // Creates a XmlProcessingInstruction with the specified name
        // and data strings.
        public virtual XmlProcessingInstruction CreateProcessingInstruction( String target, String data ) { 
            return new XmlProcessingInstruction( target, data, this );
        } 
 
        // Creates a XmlDeclaration node with the specified values.
        public virtual XmlDeclaration CreateXmlDeclaration( String version, string encoding, string standalone ) { 
            return new XmlDeclaration( version, encoding, standalone, this );
        }

        // Creates an XmlText with the specified text. 
        public virtual XmlText CreateTextNode( String text ) {
            return new XmlText( text, this ); 
        } 

        // Creates a XmlSignificantWhitespace node. 
        public virtual XmlSignificantWhitespace CreateSignificantWhitespace( string text ) {
            return new XmlSignificantWhitespace( text, this );
        }
 
        public override XPathNavigator CreateNavigator() {
            return CreateNavigator(this); 
        } 

        internal protected virtual XPathNavigator CreateNavigator(XmlNode node) { 
            XmlNodeType nodeType = node.NodeType;
            XmlNode parent;
            XmlNodeType parentType;
 
            switch (nodeType) {
                case XmlNodeType.EntityReference: 
                case XmlNodeType.Entity: 
                case XmlNodeType.DocumentType:
                case XmlNodeType.Notation: 
                case XmlNodeType.XmlDeclaration:
                    return null;
                case XmlNodeType.Text:
                case XmlNodeType.CDATA: 
                case XmlNodeType.SignificantWhitespace:
                    parent = node.ParentNode; 
                    if (parent != null) { 
                        do {
                            parentType = parent.NodeType; 
                            if (parentType == XmlNodeType.Attribute) {
                                return null;
                            }
                            else if (parentType == XmlNodeType.EntityReference) { 
                                parent = parent.ParentNode;
                            } 
                            else { 
                                break;
                            } 
                        }
                        while (parent != null);
                    }
                    node = NormalizeText(node); 
                    break;
                case XmlNodeType.Whitespace: 
                    parent = node.ParentNode; 
                    if (parent != null) {
                        do { 
                            parentType = parent.NodeType;
                            if (parentType == XmlNodeType.Document
                                || parentType == XmlNodeType.Attribute) {
                                return null; 
                            }
                            else if (parentType == XmlNodeType.EntityReference) { 
                                parent = parent.ParentNode; 
                            }
                            else { 
                                break;
                            }
                        }
                        while (parent != null); 
                    }
                    node = NormalizeText(node); 
                    break; 
                default:
                    break; 
            }
            return new DocumentXPathNavigator(this, node);
        }
 
        internal static bool IsTextNode( XmlNodeType nt ) {
            switch( nt ) { 
                case XmlNodeType.Text: 
                case XmlNodeType.CDATA:
                case XmlNodeType.Whitespace: 
                case XmlNodeType.SignificantWhitespace:
                    return true;
                default:
                    return false; 
            }
        } 
 
        private XmlNode NormalizeText( XmlNode n ) {
            XmlNode retnode = null; 
            while( IsTextNode( n.NodeType ) ) {
                retnode = n;
                n = n.PreviousSibling;
 
                if( n == null ) {
                    XmlNode intnode = retnode; 
                    while ( true ) { 
                        if  ( intnode.ParentNode != null && intnode.ParentNode.NodeType == XmlNodeType.EntityReference ) {
                            if (intnode.ParentNode.PreviousSibling != null ) { 
                                n = intnode.ParentNode.PreviousSibling;
                                break;
                            }
                            else { 
                                intnode = intnode.ParentNode;
                                if( intnode == null ) 
                                    break; 
                            }
                        } 
                        else
                            break;
                    }
                } 

                if( n == null ) 
                    break; 
                while( n.NodeType == XmlNodeType.EntityReference ) {
                    n = n.LastChild; 
                }
            }
            return retnode;
        } 

        // Creates a XmlWhitespace node. 
        public virtual XmlWhitespace CreateWhitespace( string text ) { 
            return new XmlWhitespace( text, this );
        } 

        // Returns an XmlNodeList containing
        // a list of all descendant elements that match the specified name.
        public virtual XmlNodeList GetElementsByTagName( String name ) { 
            return new XmlElementList( this, name );
        } 
 
        // DOM Level 2
 
        // Creates an XmlAttribute with the specified LocalName
        // and NamespaceURI.
        [System.Runtime.TargetedPatchingOptOutAttribute("Performance critical to inline across NGen image boundaries")]
        public XmlAttribute CreateAttribute( String qualifiedName, String namespaceURI ) { 
            string prefix = String.Empty;
            string localName = String.Empty; 
 
            SplitName( qualifiedName, out prefix, out localName );
            return CreateAttribute( prefix, localName, namespaceURI ); 
        }

        // Creates an XmlElement with the specified LocalName and
        // NamespaceURI. 
        public XmlElement CreateElement( String qualifiedName, String namespaceURI ) {
            string prefix = String.Empty; 
            string localName = String.Empty; 
            SplitName( qualifiedName, out prefix, out localName );
            return CreateElement( prefix, localName, namespaceURI ); 
        }

        // Returns a XmlNodeList containing
        // a list of all descendant elements that match the specified name. 
        public virtual XmlNodeList GetElementsByTagName( String localName, String namespaceURI ) {
            return new XmlElementList( this, localName, namespaceURI ); 
        } 

        // Returns the XmlElement with the specified ID. 
        public virtual XmlElement GetElementById( string elementId ) {
            if (htElementIdMap != null) {
                ArrayList elementList = (ArrayList)(htElementIdMap[elementId]);
                if (elementList != null) { 
                    foreach (WeakReference elemRef in elementList) {
                        XmlElement elem = (XmlElement)elemRef.Target; 
                        if (elem != null 
                            && elem.IsConnected())
                            return elem; 
                    }
                }
            }
            return null; 
        }
 
        // Imports a node from another document to this document. 
        public virtual XmlNode ImportNode( XmlNode node, bool deep ) {
            return ImportNodeInternal( node, deep ); 
        }

        private XmlNode ImportNodeInternal( XmlNode node, bool deep ) {
            XmlNode newNode = null; 

            if ( node == null ) { 
                throw new InvalidOperationException(  Res.GetString(Res.Xdom_Import_NullNode) ); 
            }
            else { 
                switch ( node.NodeType ) {
                    case XmlNodeType.Element:
                        newNode = CreateElement( node.Prefix, node.LocalName, node.NamespaceURI );
                        ImportAttributes( node, newNode ); 
                        if ( deep )
                            ImportChildren( node, newNode, deep ); 
                        break; 

                    case XmlNodeType.Attribute: 
                        Debug.Assert( ((XmlAttribute)node).Specified );
                        newNode = CreateAttribute( node.Prefix, node.LocalName, node.NamespaceURI );
                        ImportChildren( node, newNode, true );
                        break; 

                    case XmlNodeType.Text: 
                        newNode = CreateTextNode( node.Value ); 
                        break;
                    case XmlNodeType.Comment: 
                        newNode = CreateComment( node.Value);
                        break;
                    case XmlNodeType.ProcessingInstruction:
                        newNode = CreateProcessingInstruction( node.Name, node.Value ); 
                        break;
                    case XmlNodeType.XmlDeclaration: 
                        XmlDeclaration decl = (XmlDeclaration) node; 
                        newNode = CreateXmlDeclaration( decl.Version, decl.Encoding, decl.Standalone );
                        break; 
                    case XmlNodeType.CDATA:
                        newNode = CreateCDataSection( node.Value );
                        break;
                    case XmlNodeType.DocumentType: 
                        XmlDocumentType docType = (XmlDocumentType)node;
                        newNode = CreateDocumentType( docType.Name, docType.PublicId, docType.SystemId, docType.InternalSubset ); 
                        break; 
                    case XmlNodeType.DocumentFragment:
                        newNode = CreateDocumentFragment(); 
                        if (deep)
                            ImportChildren( node, newNode, deep );
                        break;
 
                    case XmlNodeType.EntityReference:
                        newNode = CreateEntityReference( node.Name ); 
                        // we don't import the children of entity reference because they might result in different 
                        // children nodes given different namesapce context in the new document.
                        break; 

                    case XmlNodeType.Whitespace:
                        newNode = CreateWhitespace( node.Value );
                        break; 

                    case XmlNodeType.SignificantWhitespace: 
                        newNode = CreateSignificantWhitespace( node.Value ); 
                        break;
 
                    default:
                        throw new InvalidOperationException( String.Format( CultureInfo.InvariantCulture, Res.GetString(Res.Xdom_Import), node.NodeType.ToString() ) );
                }
            } 

            return newNode; 
        } 

        private void ImportAttributes( XmlNode fromElem, XmlNode toElem ) { 
            int cAttr = fromElem.Attributes.Count;
            for ( int iAttr = 0; iAttr < cAttr; iAttr++ ) {
                if ( fromElem.Attributes[iAttr].Specified )
                    toElem.Attributes.SetNamedItem( ImportNodeInternal( fromElem.Attributes[iAttr], true ) ); 
            }
        } 
 
        private void ImportChildren( XmlNode fromNode, XmlNode toNode, bool deep ) {
            Debug.Assert( toNode.NodeType != XmlNodeType.EntityReference ); 
            for ( XmlNode n = fromNode.FirstChild; n != null; n = n.NextSibling ) {
                toNode.AppendChild( ImportNodeInternal( n, deep ) );
            }
        } 

        // Microsoft extensions 
 
        // Gets the XmlNameTable associated with this
        // implementation. 
        public XmlNameTable NameTable
        {
            get { return implementation.NameTable; }
        } 

        // Creates a XmlAttribute with the specified Prefix, LocalName, 
        // and NamespaceURI. 
        public virtual XmlAttribute CreateAttribute( string prefix, string localName, string namespaceURI ) {
            return new XmlAttribute( AddAttrXmlName( prefix, localName, namespaceURI, null ), this ); 
        }

        protected internal virtual XmlAttribute CreateDefaultAttribute( string prefix, string localName, string namespaceURI ) {
            return new XmlUnspecifiedAttribute( prefix, localName, namespaceURI, this ); 
        }
 
        public virtual XmlElement CreateElement( string prefix, string localName, string namespaceURI) { 
            XmlElement elem = new XmlElement( AddXmlName( prefix, localName, namespaceURI, null ), true, this );
            if ( !IsLoading ) 
                AddDefaultAttributes( elem );
            return elem;
        }
 
        // Gets or sets a value indicating whether to preserve whitespace.
        public bool PreserveWhitespace { 
            get { return preserveWhitespace;} 
            set { preserveWhitespace = value;}
        } 

        // Gets a value indicating whether the node is read-only.
        public override bool IsReadOnly {
            get { return false;} 
        }
 
        internal XmlNamedNodeMap Entities { 
            get {
                if ( entities == null ) 
                    entities = new XmlNamedNodeMap( this );
                return entities;
            }
            set { entities = value; } 
        }
 
        internal bool IsLoading { 
            get { return isLoading;}
            set { isLoading = value; } 
        }

        internal bool ActualLoadingStatus{
            get { return actualLoadingStatus;} 
            set { actualLoadingStatus = value; }
        } 
 

        // Creates a XmlNode with the specified XmlNodeType, Prefix, Name, and NamespaceURI. 
        public virtual XmlNode CreateNode( XmlNodeType type, string prefix, string name, string namespaceURI ) {
            switch (type) {
                case XmlNodeType.Element:
                    if (prefix != null) 
                        return CreateElement( prefix, name, namespaceURI );
                    else 
                        return CreateElement( name, namespaceURI ); 

                case XmlNodeType.Attribute: 
                    if (prefix != null)
                        return CreateAttribute( prefix, name, namespaceURI );
                    else
                        return CreateAttribute( name, namespaceURI ); 

                case XmlNodeType.Text: 
                    return CreateTextNode( string.Empty ); 

                case XmlNodeType.CDATA: 
                    return CreateCDataSection( string.Empty );

                case XmlNodeType.EntityReference:
                    return CreateEntityReference( name ); 

                case XmlNodeType.ProcessingInstruction: 
                    return CreateProcessingInstruction( name, string.Empty ); 

                case XmlNodeType.XmlDeclaration: 
                    return CreateXmlDeclaration( "1.0", null, null );

                case XmlNodeType.Comment:
                    return CreateComment( string.Empty ); 

                case XmlNodeType.DocumentFragment: 
                    return CreateDocumentFragment(); 

                case XmlNodeType.DocumentType: 
                    return CreateDocumentType( name, string.Empty, string.Empty, string.Empty );

                case XmlNodeType.Document:
                    return new XmlDocument(); 

                case XmlNodeType.SignificantWhitespace: 
                    return CreateSignificantWhitespace( string.Empty ); 

                case XmlNodeType.Whitespace: 
                    return CreateWhitespace( string.Empty );

                default:
                    throw new ArgumentException( Res.GetString( Res.Arg_CannotCreateNode, type ) ); 
            }
        } 
 
        // Creates an XmlNode with the specified node type, Name, and
        // NamespaceURI. 
        public virtual XmlNode CreateNode( string nodeTypeString, string name, string namespaceURI ) {
            return CreateNode( ConvertToNodeType( nodeTypeString ), name, namespaceURI );
        }
 
        // Creates an XmlNode with the specified XmlNodeType, Name, and
        // NamespaceURI. 
        public virtual XmlNode CreateNode( XmlNodeType type, string name, string namespaceURI ) { 
            return CreateNode( type, null, name, namespaceURI );
        } 

        // Creates an XmlNode object based on the information in the XmlReader.
        // The reader must be positioned on a node or attribute.
        [PermissionSetAttribute( SecurityAction.InheritanceDemand, Name = "FullTrust" )] 
        public virtual XmlNode ReadNode( XmlReader reader ) {
            XmlNode node = null; 
            try { 
                IsLoading = true;
                XmlLoader loader = new XmlLoader(); 
                node = loader.ReadCurrentNode( this, reader );
            }
            finally {
                IsLoading = false; 
            }
            return node; 
        } 

        internal XmlNodeType ConvertToNodeType( string nodeTypeString ) { 
            if ( nodeTypeString == "element" ) {
                return XmlNodeType.Element;
            }
            else if ( nodeTypeString == "attribute" ) { 
                return XmlNodeType.Attribute;
            } 
            else if ( nodeTypeString == "text" ) { 
                return XmlNodeType.Text;
            } 
            else if ( nodeTypeString == "cdatasection" ) {
                return XmlNodeType.CDATA;
            }
            else if ( nodeTypeString == "entityreference" ) { 
                return XmlNodeType.EntityReference;
            } 
            else if ( nodeTypeString == "entity" ) { 
                return XmlNodeType.Entity;
            } 
            else if ( nodeTypeString == "processinginstruction" ) {
                return XmlNodeType.ProcessingInstruction;
            }
            else if ( nodeTypeString == "comment" ) { 
                return XmlNodeType.Comment;
            } 
            else if ( nodeTypeString == "document" ) { 
                return XmlNodeType.Document;
            } 
            else if ( nodeTypeString == "documenttype" ) {
                return XmlNodeType.DocumentType;
            }
            else if ( nodeTypeString == "documentfragment" ) { 
                return XmlNodeType.DocumentFragment;
            } 
            else if ( nodeTypeString == "notation" ) { 
                return XmlNodeType.Notation;
            } 
            else if ( nodeTypeString == "significantwhitespace" ) {
                return XmlNodeType.SignificantWhitespace;
            }
            else if ( nodeTypeString == "whitespace" ) { 
                return XmlNodeType.Whitespace;
            } 
            throw new ArgumentException( Res.GetString( Res.Xdom_Invalid_NT_String, nodeTypeString ) ); 
        }
 

        private XmlTextReader SetupReader( XmlTextReader tr ) {
            tr.XmlValidatingReaderCompatibilityMode = true;
            tr.EntityHandling = EntityHandling.ExpandCharEntities; 
            if ( this.HasSetResolver )
                tr.XmlResolver = GetResolver(); 
            return tr; 
        }
 
        // Loads the XML document from the specified URL.
        [ResourceConsumption(ResourceScope.Machine)]
        [ResourceExposure(ResourceScope.Machine)]
        public virtual void Load( string filename ) { 
            XmlTextReader reader = SetupReader( new XmlTextReader( filename, NameTable ) );
            try { 
                Load( reader ); 
            }
            finally { 
                reader.Close();
            }
        }
 
        public virtual void Load( Stream inStream ) {
            XmlTextReader reader = SetupReader( new XmlTextReader( inStream, NameTable ) ); 
            try { 
                Load( reader );
            } 
            finally {
                reader.Impl.Close( false );
            }
        } 

        // Loads the XML document from the specified TextReader. 
        public virtual void Load( TextReader txtReader ) { 
            XmlTextReader reader = SetupReader( new XmlTextReader( txtReader, NameTable ) );
            try { 
                Load( reader );
            }
            finally {
                reader.Impl.Close( false ); 
            }
        } 
 
        // Loads the XML document from the specified XmlReader.
        public virtual void Load( XmlReader reader ) { 
            try {
                IsLoading = true;
                actualLoadingStatus = true;
                RemoveAll(); 
                fEntRefNodesPresent = false;
                fCDataNodesPresent  = false; 
                reportValidity = true; 

                XmlLoader loader = new XmlLoader(); 
                loader.Load( this, reader, preserveWhitespace );
            }
            finally {
                IsLoading = false; 
                actualLoadingStatus = false;
 
                // Ensure the bit is still on after loading a dtd 
                reportValidity = true;
            } 
        }

        // Loads the XML document from the specified string.
        public virtual void LoadXml( string xml ) { 
            XmlTextReader reader = SetupReader( new XmlTextReader( new StringReader( xml ), NameTable ));
            try { 
                Load( reader ); 
            }
            finally { 
                reader.Close();
            }
        }
 
        //TextEncoding is the one from XmlDeclaration if there is any
        internal Encoding TextEncoding { 
            get { 
                if ( Declaration != null )
                { 
                    string value = Declaration.Encoding;
                    if ( value.Length > 0 ) {
                        return System.Text.Encoding.GetEncoding( value );
                    } 
                }
                return null; 
            } 
        }
 
        public override string InnerText {
            set {
                throw new InvalidOperationException(Res.GetString(Res.Xdom_Document_Innertext));
            } 
        }
 
        public override string InnerXml { 
            get {
                return base.InnerXml; 
            }
            set {
                LoadXml( value );
            } 
        }
 
        // Saves the XML document to the specified file. 
        //Saves out the to the file with exact content in the XmlDocument.
        [ResourceConsumption(ResourceScope.Machine)] 
        [ResourceExposure(ResourceScope.Machine)]
        public virtual void Save( string filename ) {
            if ( DocumentElement == null )
                throw new XmlException( Res.Xml_InvalidXmlDocument, Res.GetString( Res.Xdom_NoRootEle ) ); 
            XmlDOMTextWriter xw = new XmlDOMTextWriter( filename, TextEncoding );
            try { 
                if ( preserveWhitespace == false ) 
                    xw.Formatting = Formatting.Indented;
                 WriteTo( xw ); 
                 xw.Flush();
            }
            finally {
                xw.Close(); 
            }
        } 
 
        //Saves out the to the file with exact content in the XmlDocument.
        public virtual void Save( Stream outStream ) { 
            XmlDOMTextWriter xw = new XmlDOMTextWriter( outStream, TextEncoding );
            if ( preserveWhitespace == false )
                xw.Formatting = Formatting.Indented;
            WriteTo( xw ); 
            xw.Flush();
        } 
 
        // Saves the XML document to the specified TextWriter.
        // 
        //Saves out the file with xmldeclaration which has encoding value equal to
        //that of textwriter's encoding
        public virtual void Save( TextWriter writer ) {
            XmlDOMTextWriter xw = new XmlDOMTextWriter( writer ); 
            if ( preserveWhitespace == false )
                    xw.Formatting = Formatting.Indented; 
            Save( xw ); 
        }
 
        // Saves the XML document to the specified XmlWriter.
        //
        //Saves out the file with xmldeclaration which has encoding value equal to
        //that of textwriter's encoding 
        public virtual void Save( XmlWriter w ) {
            XmlNode n = this.FirstChild; 
            if( n == null ) 
                return;
            if( w.WriteState == WriteState.Start ) { 
                if( n is XmlDeclaration ) {
                    if( Standalone.Length == 0 )
                        w.WriteStartDocument();
                    else if( Standalone == "yes" ) 
                        w.WriteStartDocument( true );
                    else if( Standalone == "no" ) 
                        w.WriteStartDocument( false ); 
                    n = n.NextSibling;
                } 
                else {
                    w.WriteStartDocument();
                }
            } 
            while( n != null ) {
                //Debug.Assert( n.NodeType != XmlNodeType.XmlDeclaration ); 
                n.WriteTo( w ); 
                n = n.NextSibling;
            } 
            w.Flush();
        }

        // Saves the node to the specified XmlWriter. 
        //
        //Writes out the to the file with exact content in the XmlDocument. 
        public override void WriteTo( XmlWriter w ) { 
            WriteContentTo( w );
        } 

        // Saves all the children of the node to the specified XmlWriter.
        //
        //Writes out the to the file with exact content in the XmlDocument. 
        public override void WriteContentTo( XmlWriter xw ) {
            foreach( XmlNode n in this ) { 
                n.WriteTo( xw ); 
            }
        } 

        public void Validate(ValidationEventHandler validationEventHandler) {
            Validate(validationEventHandler, this);
        } 

        public void Validate(ValidationEventHandler validationEventHandler, XmlNode nodeToValidate) { 
            if (this.schemas == null || this.schemas.Count == 0) { //Should we error 
                throw new InvalidOperationException(Res.GetString(Res.XmlDocument_NoSchemaInfo));
            } 
            XmlDocument parentDocument = nodeToValidate.Document;
            if (parentDocument != this) {
                throw new ArgumentException(Res.GetString(Res.XmlDocument_NodeNotFromDocument, "nodeToValidate"));
            } 
            if (nodeToValidate == this) {
                reportValidity = false; 
            } 
            DocumentSchemaValidator validator = new DocumentSchemaValidator(this, schemas, validationEventHandler);
            validator.Validate(nodeToValidate); 
            if (nodeToValidate == this) {
                reportValidity = true;
            }
        } 

        public event XmlNodeChangedEventHandler NodeInserting { 
            add { 
                onNodeInsertingDelegate += value;
            } 
            remove {
                onNodeInsertingDelegate -= value;
            }
        } 

        public event XmlNodeChangedEventHandler NodeInserted { 
            add { 
                onNodeInsertedDelegate += value;
            } 
            remove {
                onNodeInsertedDelegate -= value;
            }
        } 

        public event XmlNodeChangedEventHandler NodeRemoving { 
            add { 
                onNodeRemovingDelegate += value;
            } 
            remove {
                onNodeRemovingDelegate -= value;
            }
        } 

        public event XmlNodeChangedEventHandler NodeRemoved { 
            add { 
                onNodeRemovedDelegate += value;
            } 
            remove {
                onNodeRemovedDelegate -= value;
            }
        } 

        public event XmlNodeChangedEventHandler NodeChanging { 
            add { 
                onNodeChangingDelegate += value;
            } 
            remove {
                onNodeChangingDelegate -= value;
            }
        } 

        public event XmlNodeChangedEventHandler NodeChanged { 
            add { 
                onNodeChangedDelegate += value;
            } 
            remove {
                onNodeChangedDelegate -= value;
            }
        } 

        internal override XmlNodeChangedEventArgs GetEventArgs(XmlNode node, XmlNode oldParent, XmlNode newParent, string oldValue, string newValue, XmlNodeChangedAction action) { 
            reportValidity = false; 

            switch (action) { 
                case XmlNodeChangedAction.Insert:
                    if (onNodeInsertingDelegate == null && onNodeInsertedDelegate == null) {
                        return null;
                    } 
                    break;
                case XmlNodeChangedAction.Remove: 
                    if (onNodeRemovingDelegate == null && onNodeRemovedDelegate == null) { 
                        return null;
                    } 
                    break;
                case XmlNodeChangedAction.Change:
                    if (onNodeChangingDelegate == null && onNodeChangedDelegate == null) {
                        return null; 
                    }
                    break; 
            } 
            return new XmlNodeChangedEventArgs( node, oldParent, newParent, oldValue, newValue, action );
        } 

        internal XmlNodeChangedEventArgs GetInsertEventArgsForLoad( XmlNode node, XmlNode newParent ) {
            if (onNodeInsertingDelegate == null && onNodeInsertedDelegate == null) {
                return null; 
            }
            string nodeValue = node.Value; 
            return new XmlNodeChangedEventArgs(node, null, newParent, nodeValue, nodeValue, XmlNodeChangedAction.Insert); 
        }
 
        internal override void BeforeEvent( XmlNodeChangedEventArgs args ) {
            if ( args != null ) {
                switch ( args.Action ) {
                    case XmlNodeChangedAction.Insert: 
                        if ( onNodeInsertingDelegate != null )
                            onNodeInsertingDelegate( this, args ); 
                        break; 

                    case XmlNodeChangedAction.Remove: 
                        if ( onNodeRemovingDelegate != null )
                            onNodeRemovingDelegate( this, args );
                        break;
 
                    case XmlNodeChangedAction.Change:
                        if ( onNodeChangingDelegate != null ) 
                            onNodeChangingDelegate( this, args ); 
                        break;
                } 
            }
        }

        internal override void AfterEvent( XmlNodeChangedEventArgs args ) { 
            if ( args != null ) {
                switch ( args.Action ) { 
                    case XmlNodeChangedAction.Insert: 
                        if ( onNodeInsertedDelegate != null )
                            onNodeInsertedDelegate( this, args ); 
                        break;

                    case XmlNodeChangedAction.Remove:
                        if ( onNodeRemovedDelegate != null ) 
                            onNodeRemovedDelegate( this, args );
                        break; 
 
                    case XmlNodeChangedAction.Change:
                        if ( onNodeChangedDelegate != null ) 
                            onNodeChangedDelegate( this, args );
                        break;
                }
            } 
        }
 
        // The function such through schema info to find out if there exists a default attribute with passed in names in the passed in element 
        // If so, return the newly created default attribute (with children tree);
        // Otherwise, return null. 

        internal XmlAttribute GetDefaultAttribute( XmlElement elem, string attrPrefix, string attrLocalname, string attrNamespaceURI ) {
            SchemaInfo schInfo = DtdSchemaInfo;
            SchemaElementDecl ed = GetSchemaElementDecl( elem ); 
            if ( ed != null && ed.AttDefs != null ) {
                IDictionaryEnumerator attrDefs = ed.AttDefs.GetEnumerator(); 
                while ( attrDefs.MoveNext() ) { 
                    SchemaAttDef attdef = (SchemaAttDef)attrDefs.Value;
                    if ( attdef.Presence == SchemaDeclBase.Use.Default || 
                        attdef.Presence == SchemaDeclBase.Use.Fixed ) {
                        if ( attdef.Name.Name == attrLocalname ) {
                            if ( ( schInfo.SchemaType == SchemaType.DTD && attdef.Name.Namespace == attrPrefix ) ||
                                 ( schInfo.SchemaType != SchemaType.DTD && attdef.Name.Namespace == attrNamespaceURI ) ) { 
                                 //find a def attribute with the same name, build a default attribute and return
                                 XmlAttribute defattr = PrepareDefaultAttribute( attdef, attrPrefix, attrLocalname, attrNamespaceURI ); 
                                 return defattr; 
                            }
                        } 
                    }
                }
            }
            return null; 
        }
 
        internal String Version { 
            get {
                XmlDeclaration decl = Declaration; 
                if ( decl != null )
                    return decl.Version;
                return null;
            } 
        }
 
        internal String Encoding { 
            get {
                XmlDeclaration decl = Declaration; 
                if ( decl != null )
                    return decl.Encoding;
                return null;
            } 
        }
 
        internal String Standalone { 
            get {
                XmlDeclaration decl = Declaration; 
                if ( decl != null )
                    return decl.Standalone;
                return null;
            } 
        }
 
        internal XmlEntity GetEntityNode( String name ) { 
            if ( DocumentType != null ) {
                XmlNamedNodeMap entites = DocumentType.Entities; 
                if ( entites != null )
                    return (XmlEntity)(entites.GetNamedItem( name ));
            }
            return null; 
        }
 
        public override IXmlSchemaInfo SchemaInfo { 
            get {
                if (reportValidity) { 
                    XmlElement documentElement = DocumentElement;
                    if (documentElement != null) {
                        switch (documentElement.SchemaInfo.Validity) {
                            case XmlSchemaValidity.Valid: 
                                return ValidSchemaInfo;
                            case XmlSchemaValidity.Invalid: 
                                return InvalidSchemaInfo; 
                        }
                    } 
                }
                return NotKnownSchemaInfo;
            }
        } 

        public override String BaseURI { 
            get { return baseURI; } 
        }
 
        internal void SetBaseURI( String inBaseURI ) {
            baseURI = inBaseURI;
        }
 
        internal override XmlNode AppendChildForLoad( XmlNode newChild, XmlDocument doc ) {
            Debug.Assert( doc == this ); 
 
            if ( !IsValidChildType( newChild.NodeType ))
                throw new InvalidOperationException( Res.GetString(Res.Xdom_Node_Insert_TypeConflict) ); 

            if ( !CanInsertAfter( newChild, LastChild ) )
                throw new InvalidOperationException( Res.GetString(Res.Xdom_Node_Insert_Location) );
 
            XmlNodeChangedEventArgs args = GetInsertEventArgsForLoad( newChild, this );
 
            if ( args != null ) 
                BeforeEvent( args );
 
            XmlLinkedNode newNode = (XmlLinkedNode) newChild;

            if ( lastChild == null ) {
                newNode.next = newNode; 
            }
            else { 
                newNode.next = lastChild.next; 
                lastChild.next = newNode;
            } 

            lastChild = newNode;
            newNode.SetParentForLoad( this );
 
            if ( args != null )
                AfterEvent( args ); 
 
            return newNode;
        } 

        internal override XPathNodeType XPNodeType { get { return XPathNodeType.Root; } }

        internal bool HasEntityReferences { 
            get {
                return fEntRefNodesPresent; 
            } 
        }
 
        internal XmlAttribute NamespaceXml {
            get {
                if (namespaceXml == null) {
                    namespaceXml = new XmlAttribute(AddAttrXmlName(strXmlns, strXml, strReservedXmlns, null), this); 
                    namespaceXml.Value = strReservedXml;
                } 
                return namespaceXml; 
            }
        } 
    }
}

// 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