2016-08-03 10:59:49 +00:00
//------------------------------------------------------------------------------
// <copyright file="XmlDocument.cs" company="Microsoft">
// Copyright (c) Microsoft Corporation. All rights reserved.
// </copyright>
2017-08-21 15:34:15 +00:00
// <owner current="true" primary="true">Microsoft</owner>
2016-08-03 10:59:49 +00:00
//------------------------------------------------------------------------------
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.
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 ;
}
}
}
}