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
This book is available now!
Buy at Amazon US or
Buy at Amazon UK
- RenderingEventArgs.cs
- PackageProperties.cs
- TypeConverterAttribute.cs
- HideDisabledControlAdapter.cs
- ErrorFormatter.cs
- LinqDataSourceValidationException.cs
- ToolStripItemRenderEventArgs.cs
- ColumnWidthChangedEvent.cs
- PerspectiveCamera.cs
- SmiTypedGetterSetter.cs
- BindUriHelper.cs
- DateTimeSerializationSection.cs
- TransformerTypeCollection.cs
- SqlConnection.cs
- TraceContextRecord.cs
- HtmlControlAdapter.cs
- SoapAttributes.cs
- StringCollectionMarkupSerializer.cs
- DateTimeSerializationSection.cs
- TemplateKey.cs
- ResXBuildProvider.cs
- SettingsPropertyValue.cs
- DeclaredTypeElementCollection.cs
- AsymmetricAlgorithm.cs
- HiddenField.cs
- ConstantExpression.cs
- WsatAdminException.cs
- ModelItem.cs
- StorageRoot.cs
- LinqTreeNodeEvaluator.cs
- Table.cs
- LogicalExpr.cs
- DockPattern.cs
- X509CertificateStore.cs
- TypedServiceOperationListItem.cs
- PerformanceCounterManager.cs
- ComAdminWrapper.cs
- GridViewDeletedEventArgs.cs
- ToolStripAdornerWindowService.cs
- IncrementalReadDecoders.cs
- IMembershipProvider.cs
- OLEDB_Enum.cs
- PerfCounterSection.cs
- PerformanceCounterPermission.cs
- QilPatternVisitor.cs
- XamlSerializerUtil.cs
- InvokerUtil.cs
- OlePropertyStructs.cs
- Icon.cs
- ChangeInterceptorAttribute.cs
- StrokeNodeOperations.cs
- CachedPathData.cs
- XmlElement.cs
- SqlBuilder.cs
- SchemeSettingElementCollection.cs
- ControlPropertyNameConverter.cs
- CreateUserErrorEventArgs.cs
- ListControl.cs
- DataStreams.cs
- XmlTextWriter.cs
- ObjectStateEntryBaseUpdatableDataRecord.cs
- CodeNamespaceImportCollection.cs
- CodeTypeReferenceExpression.cs
- TraceHwndHost.cs
- ExpressionEditor.cs
- SingleKeyFrameCollection.cs
- FileDialogCustomPlacesCollection.cs
- ErrorProvider.cs
- PrintEvent.cs
- TreeIterator.cs
- UInt64Converter.cs
- XmlUtil.cs
- WsdlBuildProvider.cs
- WpfSharedBamlSchemaContext.cs
- HandlerFactoryWrapper.cs
- ButtonFieldBase.cs
- TransactionFlowBindingElement.cs
- DbProviderFactories.cs
- assemblycache.cs
- ApplicationBuildProvider.cs
- isolationinterop.cs
- DataServiceContext.cs
- FormViewRow.cs
- DeclaredTypeValidator.cs
- MouseBinding.cs
- CapabilitiesRule.cs
- SamlSecurityToken.cs
- StateDesigner.cs
- PlaceHolder.cs
- DataMisalignedException.cs
- StructuredProperty.cs
- TextTreeTextElementNode.cs
- IfAction.cs
- BinaryConverter.cs
- QueryExpression.cs
- ButtonDesigner.cs
- DbTransaction.cs
- DoubleLink.cs
- DataPagerFieldItem.cs
- SpeechSynthesizer.cs