Code:
/ Dotnetfx_Vista_SP2 / Dotnetfx_Vista_SP2 / 8.0.50727.4016 / DEVDIV / depot / DevDiv / releases / whidbey / NetFxQFE / ndp / fx / src / Xml / System / Xml / Dom / DocumentXPathNavigator.cs / 1 / DocumentXPathNavigator.cs
//------------------------------------------------------------------------------ //// Copyright (c) Microsoft Corporation. All rights reserved. // //[....] //----------------------------------------------------------------------------- using System; using System.Collections; using System.Collections.Generic; using System.Text; using System.Xml.Schema; using System.Xml.XPath; using System.Diagnostics; namespace System.Xml { internal sealed class DocumentXPathNavigator : XPathNavigator, IHasXmlNode { private XmlDocument document; // owner document private XmlNode source; // navigator position private int attributeIndex; // index in attribute collection for attribute private XmlElement namespaceParent; // parent for namespace public DocumentXPathNavigator(XmlDocument document, XmlNode node) { this.document = document; ResetPosition(node); } public DocumentXPathNavigator(DocumentXPathNavigator other) { document = other.document; source = other.source; attributeIndex = other.attributeIndex; namespaceParent = other.namespaceParent; } public override XPathNavigator Clone() { return new DocumentXPathNavigator(this); } public override void SetValue(string value) { if (value == null) { throw new ArgumentNullException("value"); } XmlNode node = source; XmlNode end; switch (node.NodeType) { case XmlNodeType.Attribute: if (((XmlAttribute)node).IsNamespace) { goto default; } node.InnerText = value; break; case XmlNodeType.Text: case XmlNodeType.CDATA: case XmlNodeType.Whitespace: case XmlNodeType.SignificantWhitespace: CalibrateText(); node = source; end = TextEnd(node); if (node != end) { if (node.IsReadOnly) { throw new InvalidOperationException(Res.GetString(Res.Xdom_Node_Modify_ReadOnly)); } DeleteToFollowingSibling(node.NextSibling, end); } goto case XmlNodeType.Element; case XmlNodeType.Element: case XmlNodeType.ProcessingInstruction: case XmlNodeType.Comment: node.InnerText = value; break; default: throw new InvalidOperationException(Res.GetString(Res.Xpn_BadPosition)); } } public override XmlNameTable NameTable { get { return document.NameTable; } } public override XPathNodeType NodeType { get { CalibrateText(); return (XPathNodeType)source.XPNodeType; } } public override string LocalName { get { return source.XPLocalName; } } public override string NamespaceURI { get { XmlAttribute attribute = source as XmlAttribute; if (attribute != null && attribute.IsNamespace) { return string.Empty; } return source.NamespaceURI; } } public override string Name { get { switch (source.NodeType) { case XmlNodeType.Element: case XmlNodeType.ProcessingInstruction: return source.Name; case XmlNodeType.Attribute: if (((XmlAttribute)source).IsNamespace) { string localName = source.LocalName; if (Ref.Equals(localName, document.strXmlns)) { return string.Empty; // xmlns declaration } return localName; // xmlns:name declaration } return source.Name; // attribute default: return string.Empty; } } } public override string Prefix { get { XmlAttribute attribute = source as XmlAttribute; if (attribute != null && attribute.IsNamespace) { return string.Empty; } return source.Prefix; } } public override string Value { get { switch (source.NodeType) { case XmlNodeType.Element: case XmlNodeType.DocumentFragment: return source.InnerText; case XmlNodeType.Document: return ValueDocument; case XmlNodeType.Text: case XmlNodeType.CDATA: case XmlNodeType.Whitespace: case XmlNodeType.SignificantWhitespace: return ValueText; default: return source.Value; } } } private string ValueDocument { get { XmlElement element = document.DocumentElement; if (element != null) { return element.InnerText; } return string.Empty; } } private string ValueText { get { CalibrateText(); string value = source.Value; XmlNode nextSibling = NextSibling(source); if (nextSibling != null && nextSibling.IsText) { StringBuilder builder = new StringBuilder(value); do { builder.Append(nextSibling.Value); nextSibling = NextSibling(nextSibling); } while (nextSibling != null && nextSibling.IsText); value = builder.ToString(); } return value; } } public override string BaseURI { get { return source.BaseURI; } } public override bool IsEmptyElement { get { XmlElement element = source as XmlElement; if (element != null) { return element.IsEmpty; } return false; } } public override string XmlLang { get { return source.XmlLang; } } public override object UnderlyingObject { get { CalibrateText(); return source; } } public override bool HasAttributes { get { XmlElement element = source as XmlElement; if (element != null && element.HasAttributes) { XmlAttributeCollection attributes = element.Attributes; for (int i = 0; i < attributes.Count; i++) { XmlAttribute attribute = attributes[i]; if (!attribute.IsNamespace) { return true; } } } return false; } } public override string GetAttribute(string localName, string namespaceURI) { return source.GetXPAttribute(localName, namespaceURI); } public override bool MoveToAttribute(string localName, string namespaceURI) { XmlElement element = source as XmlElement; if (element != null && element.HasAttributes) { XmlAttributeCollection attributes = element.Attributes; for (int i = 0; i < attributes.Count; i++) { XmlAttribute attribute = attributes[i]; if (attribute.LocalName == localName && attribute.NamespaceURI == namespaceURI) { if (!attribute.IsNamespace) { source = attribute; attributeIndex = i; return true; } else { return false; } } } } return false; } public override bool MoveToFirstAttribute() { XmlElement element = source as XmlElement; if (element != null && element.HasAttributes) { XmlAttributeCollection attributes = element.Attributes; for (int i = 0; i < attributes.Count; i++) { XmlAttribute attribute = attributes[i]; if (!attribute.IsNamespace) { source = attribute; attributeIndex = i; return true; } } } return false; } public override bool MoveToNextAttribute() { XmlAttribute attribute = source as XmlAttribute; if (attribute == null || attribute.IsNamespace) { return false; } XmlAttributeCollection attributes; if (!CheckAttributePosition(attribute, out attributes, attributeIndex) && !ResetAttributePosition(attribute, attributes, out attributeIndex)) { return false; } for (int i = attributeIndex + 1; i < attributes.Count; i++) { attribute = attributes[i]; if (!attribute.IsNamespace) { source = attribute; attributeIndex = i; return true; } } return false; } public override string GetNamespace(string name) { XmlNode node = source; while (node != null && node.NodeType != XmlNodeType.Element) { XmlAttribute attribute = node as XmlAttribute; if (attribute != null) { node = attribute.OwnerElement; } else { node = node.ParentNode; } } XmlElement element = node as XmlElement; if (element != null) { string localName; if (name != null && name.Length != 0) { localName = name; } else { localName = document.strXmlns; } string namespaceUri = document.strReservedXmlns; do { XmlAttribute attribute = element.GetAttributeNode(localName, namespaceUri); if (attribute != null) { return attribute.Value; } element = element.ParentNode as XmlElement; } while (element != null); } if (name == document.strXml) { return document.strReservedXml; } else if (name == document.strXmlns) { return document.strReservedXmlns; } return string.Empty; } public override bool MoveToNamespace(string name) { if (name == document.strXmlns) { return false; } XmlElement element = source as XmlElement; if (element != null) { string localName; if (name != null && name.Length != 0) { localName = name; } else { localName = document.strXmlns; } string namespaceUri = document.strReservedXmlns; do { XmlAttribute attribute = element.GetAttributeNode(localName, namespaceUri); if (attribute != null) { namespaceParent = (XmlElement)source; source = attribute; return true; } element = element.ParentNode as XmlElement; } while (element != null); if (name == document.strXml) { namespaceParent = (XmlElement)source; source = document.NamespaceXml; return true; } } return false; } public override bool MoveToFirstNamespace(XPathNamespaceScope scope) { XmlElement element = source as XmlElement; if (element == null) { return false; } XmlAttributeCollection attributes; int index = Int32.MaxValue; switch (scope) { case XPathNamespaceScope.Local: if (!element.HasAttributes) { return false; } attributes = element.Attributes; if (!MoveToFirstNamespaceLocal(attributes, ref index)) { return false; } source = attributes[index]; attributeIndex = index; namespaceParent = element; break; case XPathNamespaceScope.ExcludeXml: attributes = element.Attributes; if (!MoveToFirstNamespaceGlobal(ref attributes, ref index)) { return false; } XmlAttribute attribute = attributes[index]; while (Ref.Equals(attribute.LocalName, document.strXml)) { if (!MoveToNextNamespaceGlobal(ref attributes, ref index)) { return false; } attribute = attributes[index]; } source = attribute; attributeIndex = index; namespaceParent = element; break; case XPathNamespaceScope.All: attributes = element.Attributes; if (!MoveToFirstNamespaceGlobal(ref attributes, ref index)) { source = document.NamespaceXml; // attributeIndex = 0; } else { source = attributes[index]; attributeIndex = index; } namespaceParent = element; break; default: Debug.Assert(false); return false; } return true; } private static bool MoveToFirstNamespaceLocal(XmlAttributeCollection attributes, ref int index) { Debug.Assert(attributes != null); for (int i = attributes.Count - 1; i >= 0; i--) { XmlAttribute attribute = attributes[i]; if (attribute.IsNamespace) { index = i; return true; } } return false; } private static bool MoveToFirstNamespaceGlobal(ref XmlAttributeCollection attributes, ref int index) { if (MoveToFirstNamespaceLocal(attributes, ref index)) { return true; } Debug.Assert(attributes != null && attributes.parent != null); XmlElement element = attributes.parent.ParentNode as XmlElement; while (element != null) { if (element.HasAttributes) { attributes = element.Attributes; if (MoveToFirstNamespaceLocal(attributes, ref index)) { return true; } } element = element.ParentNode as XmlElement; } return false; } public override bool MoveToNextNamespace(XPathNamespaceScope scope) { XmlAttribute attribute = source as XmlAttribute; if (attribute == null || !attribute.IsNamespace) { return false; } XmlAttributeCollection attributes; int index = attributeIndex; if (!CheckAttributePosition(attribute, out attributes, index) && !ResetAttributePosition(attribute, attributes, out index)) { return false; } Debug.Assert(namespaceParent != null); switch (scope) { case XPathNamespaceScope.Local: if (attribute.OwnerElement != namespaceParent) { return false; } if (!MoveToNextNamespaceLocal(attributes, ref index)) { return false; } source = attributes[index]; attributeIndex = index; break; case XPathNamespaceScope.ExcludeXml: string localName; do { if (!MoveToNextNamespaceGlobal(ref attributes, ref index)) { return false; } attribute = attributes[index]; localName = attribute.LocalName; } while (PathHasDuplicateNamespace(attribute.OwnerElement, namespaceParent, localName) || Ref.Equals(localName, document.strXml)); source = attribute; attributeIndex = index; break; case XPathNamespaceScope.All: do { if (!MoveToNextNamespaceGlobal(ref attributes, ref index)) { if (PathHasDuplicateNamespace(null, namespaceParent, document.strXml)) { return false; } else { source = document.NamespaceXml; // attributeIndex = 0; return true; } } attribute = attributes[index]; } while (PathHasDuplicateNamespace(attribute.OwnerElement, namespaceParent, attribute.LocalName)); source = attribute; attributeIndex = index; break; default: Debug.Assert(false); return false; } return true; } private static bool MoveToNextNamespaceLocal(XmlAttributeCollection attributes, ref int index) { Debug.Assert(attributes != null); Debug.Assert(0 <= index && index < attributes.Count); for (int i = index - 1; i >= 0; i--) { XmlAttribute attribute = attributes[i]; if (attribute.IsNamespace) { index = i; return true; } } return false; } private static bool MoveToNextNamespaceGlobal(ref XmlAttributeCollection attributes, ref int index) { if (MoveToNextNamespaceLocal(attributes, ref index)) { return true; } Debug.Assert(attributes != null && attributes.parent != null); XmlElement element = attributes.parent.ParentNode as XmlElement; while (element != null) { if (element.HasAttributes) { attributes = element.Attributes; if (MoveToFirstNamespaceLocal(attributes, ref index)) { return true; } } element = element.ParentNode as XmlElement; } return false; } private bool PathHasDuplicateNamespace(XmlElement top, XmlElement bottom, string localName) { string namespaceUri = document.strReservedXmlns; while (bottom != null && bottom != top) { XmlAttribute attribute = bottom.GetAttributeNode(localName, namespaceUri); if (attribute != null) { return true; } bottom = bottom.ParentNode as XmlElement; } return false; } public override bool MoveToNext() { XmlNode sibling = NextSibling(source); if (sibling == null) { return false; } if (sibling.IsText) { if (source.IsText) { sibling = NextSibling(TextEnd(sibling)); if (sibling == null) { return false; } } } XmlNode parent = ParentNode(sibling); Debug.Assert(parent != null); while (!IsValidChild(parent, sibling)) { sibling = NextSibling(sibling); if (sibling == null) { return false; } } source = sibling; return true; } public override bool MoveToPrevious() { XmlNode sibling = PreviousSibling(source); if (sibling == null) { return false; } if (sibling.IsText) { if (source.IsText) { sibling = PreviousSibling(TextStart(sibling)); if (sibling == null) { return false; } } else { sibling = TextStart(sibling); } } XmlNode parent = ParentNode(sibling); Debug.Assert(parent != null); while (!IsValidChild(parent, sibling)) { sibling = PreviousSibling(sibling); if (sibling == null) { return false; } // if (sibling.IsText) { // sibling = TextStart(sibling); // } } source = sibling; return true; } public override bool MoveToFirst() { if (source.NodeType == XmlNodeType.Attribute) { return false; } XmlNode parent = ParentNode(source); if (parent == null) { return false; } XmlNode sibling = FirstChild(parent); Debug.Assert(sibling != null); while (!IsValidChild(parent, sibling)) { sibling = NextSibling(sibling); if (sibling == null) { return false; } } source = sibling; return true; } public override bool MoveToFirstChild() { XmlNode child; switch (source.NodeType) { case XmlNodeType.Element: child = FirstChild(source); if (child == null) { return false; } break; case XmlNodeType.DocumentFragment: case XmlNodeType.Document: child = FirstChild(source); if (child == null) { return false; } while (!IsValidChild(source, child)) { child = NextSibling(child); if (child == null) { return false; } } break; default: return false; } source = child; return true; } public override bool MoveToParent() { XmlNode parent = ParentNode(source); if (parent != null) { source = parent; return true; } XmlAttribute attribute = source as XmlAttribute; if (attribute != null) { parent = attribute.IsNamespace ? namespaceParent : attribute.OwnerElement; if (parent != null) { source = parent; namespaceParent = null; return true; } } return false; } public override void MoveToRoot() { for (;;) { XmlNode parent = source.ParentNode; if (parent == null) { XmlAttribute attribute = source as XmlAttribute; if (attribute == null) { break; } parent = attribute.IsNamespace ? namespaceParent : attribute.OwnerElement; if (parent == null) { break; } } source = parent; } namespaceParent = null; } public override bool MoveTo(XPathNavigator other) { DocumentXPathNavigator that = other as DocumentXPathNavigator; if (that != null && document == that.document) { source = that.source; attributeIndex = that.attributeIndex; namespaceParent = that.namespaceParent; return true; } return false; } public override bool MoveToId(string id) { XmlElement element = document.GetElementById(id); if (element != null) { source = element; namespaceParent = null; return true; } return false; } public override bool MoveToChild(string localName, string namespaceUri) { if (source.NodeType == XmlNodeType.Attribute) { return false; } XmlNode child = FirstChild(source); if (child != null) { do { if (child.NodeType == XmlNodeType.Element && child.LocalName == localName && child.NamespaceURI == namespaceUri) { source = child; return true; } child = NextSibling(child); } while (child != null); } return false; } public override bool MoveToChild(XPathNodeType type) { if (source.NodeType == XmlNodeType.Attribute) { return false; } XmlNode child = FirstChild(source); if (child != null) { int mask = GetContentKindMask(type); if (mask == 0) { return false; } do { if (((1 << (int)child.XPNodeType) & mask) != 0) { source = child; return true; } child = NextSibling(child); } while (child != null); } return false; } public override bool MoveToFollowing(string localName, string namespaceUri, XPathNavigator end) { XmlNode pastFollowing = null; DocumentXPathNavigator that = end as DocumentXPathNavigator; if (that != null) { if (document != that.document) { return false; } switch (that.source.NodeType) { case XmlNodeType.Attribute: that = (DocumentXPathNavigator)that.Clone(); if (!that.MoveToNonDescendant()) { return false; } break; } pastFollowing = that.source; } XmlNode following = source; if (following.NodeType == XmlNodeType.Attribute) { following = ((XmlAttribute)following).OwnerElement; if (following == null) { return false; } } do { XmlNode firstChild = following.FirstChild; if (firstChild != null) { following = firstChild; } else { for (;;) { XmlNode nextSibling = following.NextSibling; if (nextSibling != null) { following = nextSibling; break; } else { XmlNode parent = following.ParentNode; if (parent != null) { following = parent; } else { return false; } } } } if (following == pastFollowing) { return false; } } while (following.NodeType != XmlNodeType.Element || following.LocalName != localName || following.NamespaceURI != namespaceUri); source = following; return true; } public override bool MoveToFollowing(XPathNodeType type, XPathNavigator end) { XmlNode pastFollowing = null; DocumentXPathNavigator that = end as DocumentXPathNavigator; if (that != null) { if (document != that.document) { return false; } switch (that.source.NodeType) { case XmlNodeType.Attribute: that = (DocumentXPathNavigator)that.Clone(); if (!that.MoveToNonDescendant()) { return false; } break; } pastFollowing = that.source; } int mask = GetContentKindMask(type); if (mask == 0) { return false; } XmlNode following = source; switch (following.NodeType) { case XmlNodeType.Attribute: following = ((XmlAttribute)following).OwnerElement; if (following == null) { return false; } break; case XmlNodeType.Text: case XmlNodeType.CDATA: case XmlNodeType.SignificantWhitespace: case XmlNodeType.Whitespace: following = TextEnd(following); break; } do { XmlNode firstChild = following.FirstChild; if (firstChild != null) { following = firstChild; } else { for (;;) { XmlNode nextSibling = following.NextSibling; if (nextSibling != null) { following = nextSibling; break; } else { XmlNode parent = following.ParentNode; if (parent != null) { following = parent; } else { return false; } } } } if (following == pastFollowing) { return false; } } while (((1 << (int)following.XPNodeType) & mask) == 0); source = following; return true; } public override bool MoveToNext(string localName, string namespaceUri) { XmlNode sibling = NextSibling(source); if (sibling == null) { return false; } do { if (sibling.NodeType == XmlNodeType.Element && sibling.LocalName == localName && sibling.NamespaceURI == namespaceUri) { source = sibling; return true; } sibling = NextSibling(sibling); } while (sibling != null); return false; } public override bool MoveToNext(XPathNodeType type) { XmlNode sibling = NextSibling(source); if (sibling == null) { return false; } if (sibling.IsText && source.IsText) { sibling = NextSibling(TextEnd(sibling)); if (sibling == null) { return false; } } int mask = GetContentKindMask(type); if (mask == 0) { return false; } do { if (((1 << (int)sibling.XPNodeType) & mask) != 0) { source = sibling; return true; } sibling = NextSibling(sibling); } while (sibling != null); return false; } public override bool HasChildren { get { XmlNode child; switch (source.NodeType) { case XmlNodeType.Element: child = FirstChild(source); if (child == null) { return false; } return true; case XmlNodeType.DocumentFragment: case XmlNodeType.Document: child = FirstChild(source); if (child == null) { return false; } while (!IsValidChild(source, child)) { child = NextSibling(child); if (child == null) { return false; } } return true; default: return false; } } } public override bool IsSamePosition(XPathNavigator other) { DocumentXPathNavigator that = other as DocumentXPathNavigator; if (that != null) { this.CalibrateText(); that.CalibrateText(); return this.source == that.source && this.namespaceParent == that.namespaceParent; } return false; } public override bool IsDescendant(XPathNavigator other) { DocumentXPathNavigator that = other as DocumentXPathNavigator; if (that != null) { return IsDescendant(this.source, that.source); } return false; } public override IXmlSchemaInfo SchemaInfo { get { return source.SchemaInfo; } } public override bool CheckValidity(XmlSchemaSet schemas, ValidationEventHandler validationEventHandler) { XmlDocument ownerDocument; if (source.NodeType == XmlNodeType.Document) { ownerDocument = (XmlDocument)source; } else { ownerDocument = source.OwnerDocument; if (schemas != null) { throw new ArgumentException(Res.GetString(Res.XPathDocument_SchemaSetNotAllowed, null)); } } if (schemas == null && ownerDocument != null) { schemas = ownerDocument.Schemas; } if (schemas == null || schemas.Count == 0) { throw new InvalidOperationException(Res.GetString(Res.XmlDocument_NoSchemaInfo)); } DocumentSchemaValidator validator = new DocumentSchemaValidator(ownerDocument, schemas, validationEventHandler); validator.PsviAugmentation = false; return validator.Validate(source); } private static XmlNode OwnerNode(XmlNode node) { XmlNode parent = node.ParentNode; if (parent != null) { return parent; } XmlAttribute attribute = node as XmlAttribute; if (attribute != null) { return attribute.OwnerElement; } return null; } private static int GetDepth(XmlNode node) { int depth = 0; XmlNode owner = OwnerNode(node); while (owner != null) { depth++; owner = OwnerNode(owner); } return depth; } //Assuming that node1 and node2 are in the same level; Except when they are namespace nodes, they should have the same parent node //the returned value is node2's position corresponding to node1 private XmlNodeOrder Compare( XmlNode node1, XmlNode node2 ) { Debug.Assert( node1 != null ); Debug.Assert( node2 != null ); Debug.Assert( node1 != node2, "Should be handled by ComparePosition()" ); //Attribute nodes come before other children nodes except namespace nodes Debug.Assert( OwnerNode(node1) == OwnerNode(node2) ); if (node1.XPNodeType == XPathNodeType.Attribute) { if (node2.XPNodeType == XPathNodeType.Attribute) { XmlElement element = ((XmlAttribute)node1).OwnerElement; if (element.HasAttributes) { XmlAttributeCollection attributes = element.Attributes; for (int i = 0; i < attributes.Count; i++) { XmlAttribute attribute = attributes[i]; if (attribute == node1) { return XmlNodeOrder.Before; } else if (attribute == node2) { return XmlNodeOrder.After; } } } return XmlNodeOrder.Unknown; } else { return XmlNodeOrder.Before; } } if (node2.XPNodeType == XPathNodeType.Attribute) { return XmlNodeOrder.After; } //neither of the node is Namespace node or Attribute node XmlNode nextNode = node1.NextSibling; while ( nextNode != null && nextNode != node2 ) nextNode = nextNode.NextSibling; if ( nextNode == null ) //didn't meet node2 in the path to the end, thus it has to be in the front of node1 return XmlNodeOrder.After; else //met node2 in the path to the end, so node1 is at front return XmlNodeOrder.Before; } public override XmlNodeOrder ComparePosition(XPathNavigator other) { DocumentXPathNavigator that = other as DocumentXPathNavigator; if (that == null) { return XmlNodeOrder.Unknown; } this.CalibrateText(); that.CalibrateText(); if (this.source == that.source && this.namespaceParent == that.namespaceParent) { return XmlNodeOrder.Same; } if (this.namespaceParent != null || that.namespaceParent != null) { return base.ComparePosition(other); } XmlNode node1 = this.source; XmlNode node2 = that.source; XmlNode parent1 = OwnerNode(node1); XmlNode parent2 = OwnerNode(node2); if (parent1 == parent2) { if (parent1 == null) { return XmlNodeOrder.Unknown; } else { Debug.Assert(node1 != node2); return Compare(node1, node2); } } int depth1 = GetDepth(node1); int depth2 = GetDepth(node2); if (depth2 > depth1) { while (node2 != null && depth2 > depth1) { node2 = OwnerNode(node2); depth2--; } if (node1 == node2) { return XmlNodeOrder.Before; } parent2 = OwnerNode(node2); } else if (depth1 > depth2) { while (node1 != null && depth1 > depth2) { node1 = OwnerNode(node1); depth1--; } if (node1 == node2) { return XmlNodeOrder.After; } parent1 = OwnerNode(node1); } while (parent1 != null && parent2 != null) { if (parent1 == parent2) { Debug.Assert(node1 != node2); return Compare(node1, node2); } node1 = parent1; node2 = parent2; parent1 = OwnerNode(node1); parent2 = OwnerNode(node2); } return XmlNodeOrder.Unknown; } //the function just for XPathNodeList to enumerate current Node. XmlNode IHasXmlNode.GetNode() { return source; } public override XPathNodeIterator SelectDescendants( string localName, string namespaceURI, bool matchSelf ) { string nsAtom = document.NameTable.Get( namespaceURI ); if ( nsAtom == null || this.source.NodeType == XmlNodeType.Attribute ) return new DocumentXPathNodeIterator_Empty( this ); Debug.Assert( this.NodeType != XPathNodeType.Attribute && this.NodeType != XPathNodeType.Namespace && this.NodeType != XPathNodeType.All ); string localNameAtom = document.NameTable.Get( localName ); if ( localNameAtom == null ) return new DocumentXPathNodeIterator_Empty( this ); if ( localNameAtom.Length == 0 ) { if ( matchSelf ) return new DocumentXPathNodeIterator_ElemChildren_AndSelf_NoLocalName( this, nsAtom ); return new DocumentXPathNodeIterator_ElemChildren_NoLocalName( this, nsAtom ); } if ( matchSelf ) return new DocumentXPathNodeIterator_ElemChildren_AndSelf( this, localNameAtom, nsAtom ); return new DocumentXPathNodeIterator_ElemChildren( this, localNameAtom, nsAtom ); } public override XPathNodeIterator SelectDescendants( XPathNodeType nt, bool includeSelf ) { if ( nt == XPathNodeType.Element ) { XmlNodeType curNT = source.NodeType; if ( curNT != XmlNodeType.Document && curNT != XmlNodeType.Element ) { //only Document, Entity, Element node can have Element node as children ( descendant ) //entity nodes should be invisible to XPath data model return new DocumentXPathNodeIterator_Empty( this ); } if ( includeSelf ) return new DocumentXPathNodeIterator_AllElemChildren_AndSelf( this ); return new DocumentXPathNodeIterator_AllElemChildren( this ); } return base.SelectDescendants( nt, includeSelf ); } public override bool CanEdit { get { return true; } } public override XmlWriter PrependChild() { switch (source.NodeType) { case XmlNodeType.Element: case XmlNodeType.Document: case XmlNodeType.DocumentFragment: break; default: throw new InvalidOperationException(Res.GetString(Res.Xpn_BadPosition)); } DocumentXmlWriter writer = new DocumentXmlWriter(DocumentXmlWriterType.PrependChild, source, document); writer.NamespaceManager = GetNamespaceManager(source, document); return new XmlWellFormedWriter(writer, writer.Settings); } public override XmlWriter AppendChild() { switch (source.NodeType) { case XmlNodeType.Element: case XmlNodeType.Document: case XmlNodeType.DocumentFragment: break; default: throw new InvalidOperationException(Res.GetString(Res.Xpn_BadPosition)); } DocumentXmlWriter writer = new DocumentXmlWriter(DocumentXmlWriterType.AppendChild, source, document); writer.NamespaceManager = GetNamespaceManager(source, document); return new XmlWellFormedWriter(writer, writer.Settings); } public override XmlWriter InsertAfter() { XmlNode node = source; switch (node.NodeType) { case XmlNodeType.Attribute: case XmlNodeType.Document: case XmlNodeType.DocumentFragment: throw new InvalidOperationException(Res.GetString(Res.Xpn_BadPosition)); case XmlNodeType.Text: case XmlNodeType.CDATA: case XmlNodeType.SignificantWhitespace: case XmlNodeType.Whitespace: node = TextEnd(node); break; default: break; } DocumentXmlWriter writer = new DocumentXmlWriter(DocumentXmlWriterType.InsertSiblingAfter, node, document); writer.NamespaceManager = GetNamespaceManager(node.ParentNode, document); return new XmlWellFormedWriter(writer, writer.Settings); } public override XmlWriter InsertBefore() { switch (source.NodeType) { case XmlNodeType.Attribute: case XmlNodeType.Document: case XmlNodeType.DocumentFragment: throw new InvalidOperationException(Res.GetString(Res.Xpn_BadPosition)); case XmlNodeType.Text: case XmlNodeType.CDATA: case XmlNodeType.SignificantWhitespace: case XmlNodeType.Whitespace: CalibrateText(); break; default: break; } DocumentXmlWriter writer = new DocumentXmlWriter(DocumentXmlWriterType.InsertSiblingBefore, source, document); writer.NamespaceManager = GetNamespaceManager(source.ParentNode, document); return new XmlWellFormedWriter(writer, writer.Settings); } public override XmlWriter CreateAttributes() { if (source.NodeType != XmlNodeType.Element) { throw new InvalidOperationException(Res.GetString(Res.Xpn_BadPosition)); } DocumentXmlWriter writer = new DocumentXmlWriter(DocumentXmlWriterType.AppendAttribute, source, document); writer.NamespaceManager = GetNamespaceManager(source, document); return new XmlWellFormedWriter(writer, writer.Settings); } public override XmlWriter ReplaceRange(XPathNavigator lastSiblingToReplace) { DocumentXPathNavigator that = lastSiblingToReplace as DocumentXPathNavigator; if (that == null) { if (lastSiblingToReplace == null) { throw new ArgumentNullException("lastSiblingToReplace"); } else { throw new NotSupportedException(); } } this.CalibrateText(); that.CalibrateText(); XmlNode node = this.source; XmlNode end = that.source; if (node == end) { switch (node.NodeType) { case XmlNodeType.Attribute: case XmlNodeType.Document: case XmlNodeType.DocumentFragment: throw new InvalidOperationException(Res.GetString(Res.Xpn_BadPosition)); case XmlNodeType.Text: case XmlNodeType.CDATA: case XmlNodeType.SignificantWhitespace: case XmlNodeType.Whitespace: end = that.TextEnd(end); break; default: break; } } else { if (end.IsText) { end = that.TextEnd(end); } if (!IsFollowingSibling(node, end)) { throw new InvalidOperationException(Res.GetString(Res.Xpn_BadPosition)); } } DocumentXmlWriter writer = new DocumentXmlWriter(DocumentXmlWriterType.ReplaceToFollowingSibling, node, document); writer.NamespaceManager = GetNamespaceManager(node.ParentNode, document); writer.Navigator = this; writer.EndNode = end; return new XmlWellFormedWriter(writer, writer.Settings); } public override void DeleteRange(XPathNavigator lastSiblingToDelete) { DocumentXPathNavigator that = lastSiblingToDelete as DocumentXPathNavigator; if (that == null) { if (lastSiblingToDelete == null) { throw new ArgumentNullException("lastSiblingToDelete"); } else { throw new NotSupportedException(); } } this.CalibrateText(); that.CalibrateText(); XmlNode node = this.source; XmlNode end = that.source; if (node == end) { switch (node.NodeType) { case XmlNodeType.Attribute: XmlAttribute attribute = (XmlAttribute)node; if (attribute.IsNamespace) { goto default; } XmlNode parent = OwnerNode(attribute); DeleteAttribute(attribute, attributeIndex); if (parent != null) { ResetPosition(parent); } break; case XmlNodeType.Text: case XmlNodeType.CDATA: case XmlNodeType.SignificantWhitespace: case XmlNodeType.Whitespace: end = that.TextEnd(end); goto case XmlNodeType.Element; case XmlNodeType.Element: case XmlNodeType.ProcessingInstruction: case XmlNodeType.Comment: parent = OwnerNode(node); DeleteToFollowingSibling(node, end); if (parent != null) { ResetPosition(parent); } break; default: throw new InvalidOperationException(Res.GetString(Res.Xpn_BadPosition)); } } else { if (end.IsText) { end = that.TextEnd(end); } if (!IsFollowingSibling(node, end)) { throw new InvalidOperationException(Res.GetString(Res.Xpn_BadPosition)); } XmlNode parent = OwnerNode(node); DeleteToFollowingSibling(node, end); if (parent != null) { ResetPosition(parent); } } } public override void DeleteSelf() { XmlNode node = source; XmlNode end = node; switch (node.NodeType) { case XmlNodeType.Attribute: XmlAttribute attribute = (XmlAttribute)node; if (attribute.IsNamespace) { goto default; } XmlNode parent = OwnerNode(attribute); DeleteAttribute(attribute, attributeIndex); if (parent != null) { ResetPosition(parent); } break; case XmlNodeType.Text: case XmlNodeType.CDATA: case XmlNodeType.SignificantWhitespace: case XmlNodeType.Whitespace: CalibrateText(); node = source; end = TextEnd(node); goto case XmlNodeType.Element; case XmlNodeType.Element: case XmlNodeType.ProcessingInstruction: case XmlNodeType.Comment: parent = OwnerNode(node); DeleteToFollowingSibling(node, end); if (parent != null) { ResetPosition(parent); } break; default: throw new InvalidOperationException(Res.GetString(Res.Xpn_BadPosition)); } } private static void DeleteAttribute(XmlAttribute attribute, int index) { XmlAttributeCollection attributes; if (!CheckAttributePosition(attribute, out attributes, index) && !ResetAttributePosition(attribute, attributes, out index)) { throw new InvalidOperationException(Res.GetString(Res.Xpn_MissingParent)); } if (attribute.IsReadOnly) { throw new InvalidOperationException(Res.GetString(Res.Xdom_Node_Modify_ReadOnly)); } attributes.RemoveAt(index); } internal static void DeleteToFollowingSibling(XmlNode node, XmlNode end) { XmlNode parent = node.ParentNode; if (parent == null) { throw new InvalidOperationException(Res.GetString(Res.Xpn_MissingParent)); } if (node.IsReadOnly || end.IsReadOnly) { throw new InvalidOperationException(Res.GetString(Res.Xdom_Node_Modify_ReadOnly)); } while (node != end) { XmlNode temp = node; node = node.NextSibling; parent.RemoveChild(temp); } parent.RemoveChild(node); } private static XmlNamespaceManager GetNamespaceManager(XmlNode node, XmlDocument document) { XmlNamespaceManager namespaceManager = new XmlNamespaceManager(document.NameTable); Listelements = new List (); while (node != null) { XmlElement element = node as XmlElement; if (element != null && element.HasAttributes) { elements.Add(element); } node = node.ParentNode; } for (int i = elements.Count - 1; i >= 0; i--) { namespaceManager.PushScope(); XmlAttributeCollection attributes = elements[i].Attributes; for (int j = 0; j < attributes.Count; j++) { XmlAttribute attribute = attributes[j]; if (attribute.IsNamespace) { string prefix = attribute.Prefix.Length == 0 ? string.Empty : attribute.LocalName; namespaceManager.AddNamespace(prefix, attribute.Value); } } } return namespaceManager; } internal void ResetPosition(XmlNode node) { Debug.Assert(node != null, "Undefined navigator position"); Debug.Assert(node == document || node.OwnerDocument == document, "Navigator switched documents"); source = node; XmlAttribute attribute = node as XmlAttribute; if (attribute != null) { XmlElement element = attribute.OwnerElement; if (element != null) { ResetAttributePosition(attribute, element.Attributes, out attributeIndex); if (attribute.IsNamespace) { namespaceParent = element; } } } } private static bool ResetAttributePosition(XmlAttribute attribute, XmlAttributeCollection attributes, out int index) { if (attributes != null) { for (int i = 0; i < attributes.Count; i++) { if (attribute == attributes[i]) { index = i; return true; } } } index = 0; return false; } private static bool CheckAttributePosition(XmlAttribute attribute, out XmlAttributeCollection attributes, int index) { XmlElement element = attribute.OwnerElement; if (element != null) { attributes = element.Attributes; if (index >= 0 && index < attributes.Count && attribute == attributes[index]) { return true; } } else { attributes = null; } return false; } private void CalibrateText() { XmlNode text = PreviousText(source); while (text != null) { ResetPosition(text); text = PreviousText(text); } } private XmlNode ParentNode(XmlNode node) { XmlNode parent = node.ParentNode; if (!document.HasEntityReferences) { return parent; } return ParentNodeTail(parent); } private XmlNode ParentNodeTail(XmlNode parent) { while (parent != null && parent.NodeType == XmlNodeType.EntityReference) { parent = parent.ParentNode; } return parent; } private XmlNode FirstChild(XmlNode node) { XmlNode child = node.FirstChild; if (!document.HasEntityReferences) { return child; } return FirstChildTail(child); } private XmlNode FirstChildTail(XmlNode child) { while (child != null && child.NodeType == XmlNodeType.EntityReference) { child = child.FirstChild; } return child; } private XmlNode NextSibling(XmlNode node) { XmlNode sibling = node.NextSibling; if (!document.HasEntityReferences) { return sibling; } return NextSiblingTail(node, sibling); } private XmlNode NextSiblingTail(XmlNode node, XmlNode sibling) { while (sibling == null) { node = node.ParentNode; if (node == null || node.NodeType != XmlNodeType.EntityReference) { return null; } sibling = node.NextSibling; } while (sibling != null && sibling.NodeType == XmlNodeType.EntityReference) { sibling = sibling.FirstChild; } return sibling; } private XmlNode PreviousSibling(XmlNode node) { XmlNode sibling = node.PreviousSibling; if (!document.HasEntityReferences) { return sibling; } return PreviousSiblingTail(node, sibling); } private XmlNode PreviousSiblingTail(XmlNode node, XmlNode sibling) { while (sibling == null) { node = node.ParentNode; if (node == null || node.NodeType != XmlNodeType.EntityReference) { return null; } sibling = node.PreviousSibling; } while (sibling != null && sibling.NodeType == XmlNodeType.EntityReference) { sibling = sibling.LastChild; } return sibling; } private XmlNode PreviousText(XmlNode node) { XmlNode text = node.PreviousText; if (!document.HasEntityReferences) { return text; } return PreviousTextTail(node, text); } private XmlNode PreviousTextTail(XmlNode node, XmlNode text) { if (text != null) { return text; } if (!node.IsText) { return null; } XmlNode sibling = node.PreviousSibling; while (sibling == null) { node = node.ParentNode; if (node == null || node.NodeType != XmlNodeType.EntityReference) { return null; } sibling = node.PreviousSibling; } while (sibling != null) { switch (sibling.NodeType) { case XmlNodeType.EntityReference: sibling = sibling.LastChild; break; case XmlNodeType.Text: case XmlNodeType.CDATA: case XmlNodeType.Whitespace: case XmlNodeType.SignificantWhitespace: return sibling; default: return null; } } return null; } internal static bool IsFollowingSibling(XmlNode left, XmlNode right) { for (;;) { left = left.NextSibling; if (left == null) { break; } if (left == right) { return true; } } return false; } private static bool IsDescendant(XmlNode top, XmlNode bottom) { for (;;) { XmlNode parent = bottom.ParentNode; if (parent == null) { XmlAttribute attribute = bottom as XmlAttribute; if (attribute == null) { break; } parent = attribute.OwnerElement; if (parent == null) { break; } } bottom = parent; if (top == bottom) { return true; } } return false; } private static bool IsValidChild(XmlNode parent, XmlNode child) { switch (parent.NodeType) { case XmlNodeType.Element: return true; case XmlNodeType.DocumentFragment: switch (child.NodeType) { case XmlNodeType.Element: case XmlNodeType.Text: case XmlNodeType.CDATA: case XmlNodeType.ProcessingInstruction: case XmlNodeType.Comment: case XmlNodeType.Whitespace: case XmlNodeType.SignificantWhitespace: return true; } break; case XmlNodeType.Document: switch (child.NodeType) { case XmlNodeType.Element: case XmlNodeType.ProcessingInstruction: case XmlNodeType.Comment: return true; } break; default: break; } return false; } private XmlNode TextStart(XmlNode node) { XmlNode start; do { start = node; node = PreviousSibling(node); } while (node != null && node.IsText); return start; } private XmlNode TextEnd(XmlNode node) { XmlNode end; do { end = node; node = NextSibling(node); } while (node != null && node.IsText); return end; } } // An iterator that matches no nodes internal sealed class DocumentXPathNodeIterator_Empty : XPathNodeIterator { private XPathNavigator nav; internal DocumentXPathNodeIterator_Empty( DocumentXPathNavigator nav ) { this.nav = nav.Clone(); } internal DocumentXPathNodeIterator_Empty( DocumentXPathNodeIterator_Empty other ) { this.nav = other.nav.Clone(); } public override XPathNodeIterator Clone() { return new DocumentXPathNodeIterator_Empty( this ); } public override bool MoveNext() { return false; } public override XPathNavigator Current { get { return nav; } } public override int CurrentPosition { get { return 0; } } public override int Count { get { return 0; } } } // An iterator that can match any child elements that match the Match condition (overrided in the derived class) internal abstract class DocumentXPathNodeIterator_ElemDescendants : XPathNodeIterator { private DocumentXPathNavigator nav; private int level; private int position; internal DocumentXPathNodeIterator_ElemDescendants( DocumentXPathNavigator nav ) { this.nav = (DocumentXPathNavigator)(nav.Clone()); this.level = 0; this.position = 0; } internal DocumentXPathNodeIterator_ElemDescendants( DocumentXPathNodeIterator_ElemDescendants other ) { this.nav = (DocumentXPathNavigator)(other.nav.Clone()); this.level = other.level; this.position = other.position; } protected abstract bool Match( XmlNode node ); public override XPathNavigator Current { get { return nav; } } public override int CurrentPosition { get { return position; } } protected void SetPosition( int pos ) { position = pos; } public override bool MoveNext() { for (;;) { if (nav.MoveToFirstChild()) { level++; } else { if (level == 0) { return false; } while (!nav.MoveToNext()) { level--; if (level == 0) { return false; } if (!nav.MoveToParent()) { return false; } } } XmlNode node = (XmlNode)nav.UnderlyingObject; if (node.NodeType == XmlNodeType.Element && Match(node)) { position++; return true; } } } } // Iterate over all element children irrespective of the localName and namespace internal class DocumentXPathNodeIterator_AllElemChildren : DocumentXPathNodeIterator_ElemDescendants { internal DocumentXPathNodeIterator_AllElemChildren( DocumentXPathNavigator nav ) : base( nav ) { Debug.Assert( ((XmlNode)nav.UnderlyingObject).NodeType != XmlNodeType.Attribute ); } internal DocumentXPathNodeIterator_AllElemChildren( DocumentXPathNodeIterator_AllElemChildren other ) : base( other ) { } public override XPathNodeIterator Clone() { return new DocumentXPathNodeIterator_AllElemChildren( this ); } protected override bool Match( XmlNode node ) { Debug.Assert( node != null ); return ( node.NodeType == XmlNodeType.Element ); } } // Iterate over all element children irrespective of the localName and namespace, include the self node when testing for localName/ns internal sealed class DocumentXPathNodeIterator_AllElemChildren_AndSelf : DocumentXPathNodeIterator_AllElemChildren { internal DocumentXPathNodeIterator_AllElemChildren_AndSelf( DocumentXPathNavigator nav ) : base( nav ) { } internal DocumentXPathNodeIterator_AllElemChildren_AndSelf( DocumentXPathNodeIterator_AllElemChildren_AndSelf other ) : base( other ) { } public override XPathNodeIterator Clone() { return new DocumentXPathNodeIterator_AllElemChildren_AndSelf( this ); } public override bool MoveNext() { if( CurrentPosition == 0 ) { DocumentXPathNavigator nav = (DocumentXPathNavigator)this.Current; XmlNode node = (XmlNode)nav.UnderlyingObject; if ( node.NodeType == XmlNodeType.Element && Match( node ) ) { SetPosition( 1 ); return true; } } return base.MoveNext(); } } // Iterate over all element children that have a given namespace but irrespective of the localName internal class DocumentXPathNodeIterator_ElemChildren_NoLocalName : DocumentXPathNodeIterator_ElemDescendants { private string nsAtom; internal DocumentXPathNodeIterator_ElemChildren_NoLocalName( DocumentXPathNavigator nav, string nsAtom ) : base( nav ) { Debug.Assert( ((XmlNode)nav.UnderlyingObject).NodeType != XmlNodeType.Attribute ); Debug.Assert( Ref.Equal(nav.NameTable.Get( nsAtom ), nsAtom) ); this.nsAtom = nsAtom; } internal DocumentXPathNodeIterator_ElemChildren_NoLocalName( DocumentXPathNodeIterator_ElemChildren_NoLocalName other ) : base( other ) { this.nsAtom = other.nsAtom; } public override XPathNodeIterator Clone() { return new DocumentXPathNodeIterator_ElemChildren_NoLocalName( this ); } protected override bool Match( XmlNode node ) { Debug.Assert( node != null ); Debug.Assert( node.NodeType == XmlNodeType.Element ); return Ref.Equal(node.NamespaceURI, nsAtom); } } // Iterate over all element children that have a given namespace but irrespective of the localName, include self node when checking for ns internal sealed class DocumentXPathNodeIterator_ElemChildren_AndSelf_NoLocalName : DocumentXPathNodeIterator_ElemChildren_NoLocalName { internal DocumentXPathNodeIterator_ElemChildren_AndSelf_NoLocalName( DocumentXPathNavigator nav, string nsAtom ) : base( nav, nsAtom ) { } internal DocumentXPathNodeIterator_ElemChildren_AndSelf_NoLocalName( DocumentXPathNodeIterator_ElemChildren_AndSelf_NoLocalName other ) : base( other ) { } public override XPathNodeIterator Clone() { return new DocumentXPathNodeIterator_ElemChildren_AndSelf_NoLocalName( this ); } public override bool MoveNext() { if( CurrentPosition == 0 ) { DocumentXPathNavigator nav = (DocumentXPathNavigator)this.Current; XmlNode node = (XmlNode)nav.UnderlyingObject; if ( node.NodeType == XmlNodeType.Element && Match( node ) ) { SetPosition( 1 ); return true; } } return base.MoveNext(); } } // Iterate over all element children that have a given name and namespace internal class DocumentXPathNodeIterator_ElemChildren : DocumentXPathNodeIterator_ElemDescendants { protected string localNameAtom; protected string nsAtom; internal DocumentXPathNodeIterator_ElemChildren( DocumentXPathNavigator nav, string localNameAtom, string nsAtom ) : base( nav ) { Debug.Assert( ((XmlNode)nav.UnderlyingObject).NodeType != XmlNodeType.Attribute ); Debug.Assert( Ref.Equal(nav.NameTable.Get( localNameAtom ), localNameAtom) ); Debug.Assert( Ref.Equal(nav.NameTable.Get( nsAtom ), nsAtom) ); Debug.Assert( localNameAtom.Length > 0 ); // Use DocumentXPathNodeIterator_ElemChildren_NoLocalName class for special magic value of localNameAtom this.localNameAtom = localNameAtom; this.nsAtom = nsAtom; } internal DocumentXPathNodeIterator_ElemChildren( DocumentXPathNodeIterator_ElemChildren other ) : base( other ) { this.localNameAtom = other.localNameAtom; this.nsAtom = other.nsAtom; } public override XPathNodeIterator Clone() { return new DocumentXPathNodeIterator_ElemChildren( this ); } protected override bool Match( XmlNode node ) { Debug.Assert( node != null ); Debug.Assert( node.NodeType == XmlNodeType.Element ); return Ref.Equal(node.LocalName, localNameAtom) && Ref.Equal(node.NamespaceURI, nsAtom); } } // Iterate over all elem children and itself and check for the given localName (including the magic value "") and namespace internal sealed class DocumentXPathNodeIterator_ElemChildren_AndSelf : DocumentXPathNodeIterator_ElemChildren { internal DocumentXPathNodeIterator_ElemChildren_AndSelf( DocumentXPathNavigator nav, string localNameAtom, string nsAtom ) : base( nav, localNameAtom, nsAtom ) { Debug.Assert( localNameAtom.Length > 0 ); // Use DocumentXPathNodeIterator_ElemChildren_AndSelf_NoLocalName if localName == String.Empty } internal DocumentXPathNodeIterator_ElemChildren_AndSelf( DocumentXPathNodeIterator_ElemChildren_AndSelf other ) : base( other ) { } public override XPathNodeIterator Clone() { return new DocumentXPathNodeIterator_ElemChildren_AndSelf( this ); } public override bool MoveNext() { if( CurrentPosition == 0 ) { DocumentXPathNavigator nav = (DocumentXPathNavigator)this.Current; XmlNode node = (XmlNode)nav.UnderlyingObject; if ( node.NodeType == XmlNodeType.Element && Match( node ) ) { SetPosition( 1 ); return true; } } return base.MoveNext(); } } } // File provided for Reference Use Only by Microsoft Corporation (c) 2007. //------------------------------------------------------------------------------ // // Copyright (c) Microsoft Corporation. All rights reserved. // //[....] //----------------------------------------------------------------------------- using System; using System.Collections; using System.Collections.Generic; using System.Text; using System.Xml.Schema; using System.Xml.XPath; using System.Diagnostics; namespace System.Xml { internal sealed class DocumentXPathNavigator : XPathNavigator, IHasXmlNode { private XmlDocument document; // owner document private XmlNode source; // navigator position private int attributeIndex; // index in attribute collection for attribute private XmlElement namespaceParent; // parent for namespace public DocumentXPathNavigator(XmlDocument document, XmlNode node) { this.document = document; ResetPosition(node); } public DocumentXPathNavigator(DocumentXPathNavigator other) { document = other.document; source = other.source; attributeIndex = other.attributeIndex; namespaceParent = other.namespaceParent; } public override XPathNavigator Clone() { return new DocumentXPathNavigator(this); } public override void SetValue(string value) { if (value == null) { throw new ArgumentNullException("value"); } XmlNode node = source; XmlNode end; switch (node.NodeType) { case XmlNodeType.Attribute: if (((XmlAttribute)node).IsNamespace) { goto default; } node.InnerText = value; break; case XmlNodeType.Text: case XmlNodeType.CDATA: case XmlNodeType.Whitespace: case XmlNodeType.SignificantWhitespace: CalibrateText(); node = source; end = TextEnd(node); if (node != end) { if (node.IsReadOnly) { throw new InvalidOperationException(Res.GetString(Res.Xdom_Node_Modify_ReadOnly)); } DeleteToFollowingSibling(node.NextSibling, end); } goto case XmlNodeType.Element; case XmlNodeType.Element: case XmlNodeType.ProcessingInstruction: case XmlNodeType.Comment: node.InnerText = value; break; default: throw new InvalidOperationException(Res.GetString(Res.Xpn_BadPosition)); } } public override XmlNameTable NameTable { get { return document.NameTable; } } public override XPathNodeType NodeType { get { CalibrateText(); return (XPathNodeType)source.XPNodeType; } } public override string LocalName { get { return source.XPLocalName; } } public override string NamespaceURI { get { XmlAttribute attribute = source as XmlAttribute; if (attribute != null && attribute.IsNamespace) { return string.Empty; } return source.NamespaceURI; } } public override string Name { get { switch (source.NodeType) { case XmlNodeType.Element: case XmlNodeType.ProcessingInstruction: return source.Name; case XmlNodeType.Attribute: if (((XmlAttribute)source).IsNamespace) { string localName = source.LocalName; if (Ref.Equals(localName, document.strXmlns)) { return string.Empty; // xmlns declaration } return localName; // xmlns:name declaration } return source.Name; // attribute default: return string.Empty; } } } public override string Prefix { get { XmlAttribute attribute = source as XmlAttribute; if (attribute != null && attribute.IsNamespace) { return string.Empty; } return source.Prefix; } } public override string Value { get { switch (source.NodeType) { case XmlNodeType.Element: case XmlNodeType.DocumentFragment: return source.InnerText; case XmlNodeType.Document: return ValueDocument; case XmlNodeType.Text: case XmlNodeType.CDATA: case XmlNodeType.Whitespace: case XmlNodeType.SignificantWhitespace: return ValueText; default: return source.Value; } } } private string ValueDocument { get { XmlElement element = document.DocumentElement; if (element != null) { return element.InnerText; } return string.Empty; } } private string ValueText { get { CalibrateText(); string value = source.Value; XmlNode nextSibling = NextSibling(source); if (nextSibling != null && nextSibling.IsText) { StringBuilder builder = new StringBuilder(value); do { builder.Append(nextSibling.Value); nextSibling = NextSibling(nextSibling); } while (nextSibling != null && nextSibling.IsText); value = builder.ToString(); } return value; } } public override string BaseURI { get { return source.BaseURI; } } public override bool IsEmptyElement { get { XmlElement element = source as XmlElement; if (element != null) { return element.IsEmpty; } return false; } } public override string XmlLang { get { return source.XmlLang; } } public override object UnderlyingObject { get { CalibrateText(); return source; } } public override bool HasAttributes { get { XmlElement element = source as XmlElement; if (element != null && element.HasAttributes) { XmlAttributeCollection attributes = element.Attributes; for (int i = 0; i < attributes.Count; i++) { XmlAttribute attribute = attributes[i]; if (!attribute.IsNamespace) { return true; } } } return false; } } public override string GetAttribute(string localName, string namespaceURI) { return source.GetXPAttribute(localName, namespaceURI); } public override bool MoveToAttribute(string localName, string namespaceURI) { XmlElement element = source as XmlElement; if (element != null && element.HasAttributes) { XmlAttributeCollection attributes = element.Attributes; for (int i = 0; i < attributes.Count; i++) { XmlAttribute attribute = attributes[i]; if (attribute.LocalName == localName && attribute.NamespaceURI == namespaceURI) { if (!attribute.IsNamespace) { source = attribute; attributeIndex = i; return true; } else { return false; } } } } return false; } public override bool MoveToFirstAttribute() { XmlElement element = source as XmlElement; if (element != null && element.HasAttributes) { XmlAttributeCollection attributes = element.Attributes; for (int i = 0; i < attributes.Count; i++) { XmlAttribute attribute = attributes[i]; if (!attribute.IsNamespace) { source = attribute; attributeIndex = i; return true; } } } return false; } public override bool MoveToNextAttribute() { XmlAttribute attribute = source as XmlAttribute; if (attribute == null || attribute.IsNamespace) { return false; } XmlAttributeCollection attributes; if (!CheckAttributePosition(attribute, out attributes, attributeIndex) && !ResetAttributePosition(attribute, attributes, out attributeIndex)) { return false; } for (int i = attributeIndex + 1; i < attributes.Count; i++) { attribute = attributes[i]; if (!attribute.IsNamespace) { source = attribute; attributeIndex = i; return true; } } return false; } public override string GetNamespace(string name) { XmlNode node = source; while (node != null && node.NodeType != XmlNodeType.Element) { XmlAttribute attribute = node as XmlAttribute; if (attribute != null) { node = attribute.OwnerElement; } else { node = node.ParentNode; } } XmlElement element = node as XmlElement; if (element != null) { string localName; if (name != null && name.Length != 0) { localName = name; } else { localName = document.strXmlns; } string namespaceUri = document.strReservedXmlns; do { XmlAttribute attribute = element.GetAttributeNode(localName, namespaceUri); if (attribute != null) { return attribute.Value; } element = element.ParentNode as XmlElement; } while (element != null); } if (name == document.strXml) { return document.strReservedXml; } else if (name == document.strXmlns) { return document.strReservedXmlns; } return string.Empty; } public override bool MoveToNamespace(string name) { if (name == document.strXmlns) { return false; } XmlElement element = source as XmlElement; if (element != null) { string localName; if (name != null && name.Length != 0) { localName = name; } else { localName = document.strXmlns; } string namespaceUri = document.strReservedXmlns; do { XmlAttribute attribute = element.GetAttributeNode(localName, namespaceUri); if (attribute != null) { namespaceParent = (XmlElement)source; source = attribute; return true; } element = element.ParentNode as XmlElement; } while (element != null); if (name == document.strXml) { namespaceParent = (XmlElement)source; source = document.NamespaceXml; return true; } } return false; } public override bool MoveToFirstNamespace(XPathNamespaceScope scope) { XmlElement element = source as XmlElement; if (element == null) { return false; } XmlAttributeCollection attributes; int index = Int32.MaxValue; switch (scope) { case XPathNamespaceScope.Local: if (!element.HasAttributes) { return false; } attributes = element.Attributes; if (!MoveToFirstNamespaceLocal(attributes, ref index)) { return false; } source = attributes[index]; attributeIndex = index; namespaceParent = element; break; case XPathNamespaceScope.ExcludeXml: attributes = element.Attributes; if (!MoveToFirstNamespaceGlobal(ref attributes, ref index)) { return false; } XmlAttribute attribute = attributes[index]; while (Ref.Equals(attribute.LocalName, document.strXml)) { if (!MoveToNextNamespaceGlobal(ref attributes, ref index)) { return false; } attribute = attributes[index]; } source = attribute; attributeIndex = index; namespaceParent = element; break; case XPathNamespaceScope.All: attributes = element.Attributes; if (!MoveToFirstNamespaceGlobal(ref attributes, ref index)) { source = document.NamespaceXml; // attributeIndex = 0; } else { source = attributes[index]; attributeIndex = index; } namespaceParent = element; break; default: Debug.Assert(false); return false; } return true; } private static bool MoveToFirstNamespaceLocal(XmlAttributeCollection attributes, ref int index) { Debug.Assert(attributes != null); for (int i = attributes.Count - 1; i >= 0; i--) { XmlAttribute attribute = attributes[i]; if (attribute.IsNamespace) { index = i; return true; } } return false; } private static bool MoveToFirstNamespaceGlobal(ref XmlAttributeCollection attributes, ref int index) { if (MoveToFirstNamespaceLocal(attributes, ref index)) { return true; } Debug.Assert(attributes != null && attributes.parent != null); XmlElement element = attributes.parent.ParentNode as XmlElement; while (element != null) { if (element.HasAttributes) { attributes = element.Attributes; if (MoveToFirstNamespaceLocal(attributes, ref index)) { return true; } } element = element.ParentNode as XmlElement; } return false; } public override bool MoveToNextNamespace(XPathNamespaceScope scope) { XmlAttribute attribute = source as XmlAttribute; if (attribute == null || !attribute.IsNamespace) { return false; } XmlAttributeCollection attributes; int index = attributeIndex; if (!CheckAttributePosition(attribute, out attributes, index) && !ResetAttributePosition(attribute, attributes, out index)) { return false; } Debug.Assert(namespaceParent != null); switch (scope) { case XPathNamespaceScope.Local: if (attribute.OwnerElement != namespaceParent) { return false; } if (!MoveToNextNamespaceLocal(attributes, ref index)) { return false; } source = attributes[index]; attributeIndex = index; break; case XPathNamespaceScope.ExcludeXml: string localName; do { if (!MoveToNextNamespaceGlobal(ref attributes, ref index)) { return false; } attribute = attributes[index]; localName = attribute.LocalName; } while (PathHasDuplicateNamespace(attribute.OwnerElement, namespaceParent, localName) || Ref.Equals(localName, document.strXml)); source = attribute; attributeIndex = index; break; case XPathNamespaceScope.All: do { if (!MoveToNextNamespaceGlobal(ref attributes, ref index)) { if (PathHasDuplicateNamespace(null, namespaceParent, document.strXml)) { return false; } else { source = document.NamespaceXml; // attributeIndex = 0; return true; } } attribute = attributes[index]; } while (PathHasDuplicateNamespace(attribute.OwnerElement, namespaceParent, attribute.LocalName)); source = attribute; attributeIndex = index; break; default: Debug.Assert(false); return false; } return true; } private static bool MoveToNextNamespaceLocal(XmlAttributeCollection attributes, ref int index) { Debug.Assert(attributes != null); Debug.Assert(0 <= index && index < attributes.Count); for (int i = index - 1; i >= 0; i--) { XmlAttribute attribute = attributes[i]; if (attribute.IsNamespace) { index = i; return true; } } return false; } private static bool MoveToNextNamespaceGlobal(ref XmlAttributeCollection attributes, ref int index) { if (MoveToNextNamespaceLocal(attributes, ref index)) { return true; } Debug.Assert(attributes != null && attributes.parent != null); XmlElement element = attributes.parent.ParentNode as XmlElement; while (element != null) { if (element.HasAttributes) { attributes = element.Attributes; if (MoveToFirstNamespaceLocal(attributes, ref index)) { return true; } } element = element.ParentNode as XmlElement; } return false; } private bool PathHasDuplicateNamespace(XmlElement top, XmlElement bottom, string localName) { string namespaceUri = document.strReservedXmlns; while (bottom != null && bottom != top) { XmlAttribute attribute = bottom.GetAttributeNode(localName, namespaceUri); if (attribute != null) { return true; } bottom = bottom.ParentNode as XmlElement; } return false; } public override bool MoveToNext() { XmlNode sibling = NextSibling(source); if (sibling == null) { return false; } if (sibling.IsText) { if (source.IsText) { sibling = NextSibling(TextEnd(sibling)); if (sibling == null) { return false; } } } XmlNode parent = ParentNode(sibling); Debug.Assert(parent != null); while (!IsValidChild(parent, sibling)) { sibling = NextSibling(sibling); if (sibling == null) { return false; } } source = sibling; return true; } public override bool MoveToPrevious() { XmlNode sibling = PreviousSibling(source); if (sibling == null) { return false; } if (sibling.IsText) { if (source.IsText) { sibling = PreviousSibling(TextStart(sibling)); if (sibling == null) { return false; } } else { sibling = TextStart(sibling); } } XmlNode parent = ParentNode(sibling); Debug.Assert(parent != null); while (!IsValidChild(parent, sibling)) { sibling = PreviousSibling(sibling); if (sibling == null) { return false; } // if (sibling.IsText) { // sibling = TextStart(sibling); // } } source = sibling; return true; } public override bool MoveToFirst() { if (source.NodeType == XmlNodeType.Attribute) { return false; } XmlNode parent = ParentNode(source); if (parent == null) { return false; } XmlNode sibling = FirstChild(parent); Debug.Assert(sibling != null); while (!IsValidChild(parent, sibling)) { sibling = NextSibling(sibling); if (sibling == null) { return false; } } source = sibling; return true; } public override bool MoveToFirstChild() { XmlNode child; switch (source.NodeType) { case XmlNodeType.Element: child = FirstChild(source); if (child == null) { return false; } break; case XmlNodeType.DocumentFragment: case XmlNodeType.Document: child = FirstChild(source); if (child == null) { return false; } while (!IsValidChild(source, child)) { child = NextSibling(child); if (child == null) { return false; } } break; default: return false; } source = child; return true; } public override bool MoveToParent() { XmlNode parent = ParentNode(source); if (parent != null) { source = parent; return true; } XmlAttribute attribute = source as XmlAttribute; if (attribute != null) { parent = attribute.IsNamespace ? namespaceParent : attribute.OwnerElement; if (parent != null) { source = parent; namespaceParent = null; return true; } } return false; } public override void MoveToRoot() { for (;;) { XmlNode parent = source.ParentNode; if (parent == null) { XmlAttribute attribute = source as XmlAttribute; if (attribute == null) { break; } parent = attribute.IsNamespace ? namespaceParent : attribute.OwnerElement; if (parent == null) { break; } } source = parent; } namespaceParent = null; } public override bool MoveTo(XPathNavigator other) { DocumentXPathNavigator that = other as DocumentXPathNavigator; if (that != null && document == that.document) { source = that.source; attributeIndex = that.attributeIndex; namespaceParent = that.namespaceParent; return true; } return false; } public override bool MoveToId(string id) { XmlElement element = document.GetElementById(id); if (element != null) { source = element; namespaceParent = null; return true; } return false; } public override bool MoveToChild(string localName, string namespaceUri) { if (source.NodeType == XmlNodeType.Attribute) { return false; } XmlNode child = FirstChild(source); if (child != null) { do { if (child.NodeType == XmlNodeType.Element && child.LocalName == localName && child.NamespaceURI == namespaceUri) { source = child; return true; } child = NextSibling(child); } while (child != null); } return false; } public override bool MoveToChild(XPathNodeType type) { if (source.NodeType == XmlNodeType.Attribute) { return false; } XmlNode child = FirstChild(source); if (child != null) { int mask = GetContentKindMask(type); if (mask == 0) { return false; } do { if (((1 << (int)child.XPNodeType) & mask) != 0) { source = child; return true; } child = NextSibling(child); } while (child != null); } return false; } public override bool MoveToFollowing(string localName, string namespaceUri, XPathNavigator end) { XmlNode pastFollowing = null; DocumentXPathNavigator that = end as DocumentXPathNavigator; if (that != null) { if (document != that.document) { return false; } switch (that.source.NodeType) { case XmlNodeType.Attribute: that = (DocumentXPathNavigator)that.Clone(); if (!that.MoveToNonDescendant()) { return false; } break; } pastFollowing = that.source; } XmlNode following = source; if (following.NodeType == XmlNodeType.Attribute) { following = ((XmlAttribute)following).OwnerElement; if (following == null) { return false; } } do { XmlNode firstChild = following.FirstChild; if (firstChild != null) { following = firstChild; } else { for (;;) { XmlNode nextSibling = following.NextSibling; if (nextSibling != null) { following = nextSibling; break; } else { XmlNode parent = following.ParentNode; if (parent != null) { following = parent; } else { return false; } } } } if (following == pastFollowing) { return false; } } while (following.NodeType != XmlNodeType.Element || following.LocalName != localName || following.NamespaceURI != namespaceUri); source = following; return true; } public override bool MoveToFollowing(XPathNodeType type, XPathNavigator end) { XmlNode pastFollowing = null; DocumentXPathNavigator that = end as DocumentXPathNavigator; if (that != null) { if (document != that.document) { return false; } switch (that.source.NodeType) { case XmlNodeType.Attribute: that = (DocumentXPathNavigator)that.Clone(); if (!that.MoveToNonDescendant()) { return false; } break; } pastFollowing = that.source; } int mask = GetContentKindMask(type); if (mask == 0) { return false; } XmlNode following = source; switch (following.NodeType) { case XmlNodeType.Attribute: following = ((XmlAttribute)following).OwnerElement; if (following == null) { return false; } break; case XmlNodeType.Text: case XmlNodeType.CDATA: case XmlNodeType.SignificantWhitespace: case XmlNodeType.Whitespace: following = TextEnd(following); break; } do { XmlNode firstChild = following.FirstChild; if (firstChild != null) { following = firstChild; } else { for (;;) { XmlNode nextSibling = following.NextSibling; if (nextSibling != null) { following = nextSibling; break; } else { XmlNode parent = following.ParentNode; if (parent != null) { following = parent; } else { return false; } } } } if (following == pastFollowing) { return false; } } while (((1 << (int)following.XPNodeType) & mask) == 0); source = following; return true; } public override bool MoveToNext(string localName, string namespaceUri) { XmlNode sibling = NextSibling(source); if (sibling == null) { return false; } do { if (sibling.NodeType == XmlNodeType.Element && sibling.LocalName == localName && sibling.NamespaceURI == namespaceUri) { source = sibling; return true; } sibling = NextSibling(sibling); } while (sibling != null); return false; } public override bool MoveToNext(XPathNodeType type) { XmlNode sibling = NextSibling(source); if (sibling == null) { return false; } if (sibling.IsText && source.IsText) { sibling = NextSibling(TextEnd(sibling)); if (sibling == null) { return false; } } int mask = GetContentKindMask(type); if (mask == 0) { return false; } do { if (((1 << (int)sibling.XPNodeType) & mask) != 0) { source = sibling; return true; } sibling = NextSibling(sibling); } while (sibling != null); return false; } public override bool HasChildren { get { XmlNode child; switch (source.NodeType) { case XmlNodeType.Element: child = FirstChild(source); if (child == null) { return false; } return true; case XmlNodeType.DocumentFragment: case XmlNodeType.Document: child = FirstChild(source); if (child == null) { return false; } while (!IsValidChild(source, child)) { child = NextSibling(child); if (child == null) { return false; } } return true; default: return false; } } } public override bool IsSamePosition(XPathNavigator other) { DocumentXPathNavigator that = other as DocumentXPathNavigator; if (that != null) { this.CalibrateText(); that.CalibrateText(); return this.source == that.source && this.namespaceParent == that.namespaceParent; } return false; } public override bool IsDescendant(XPathNavigator other) { DocumentXPathNavigator that = other as DocumentXPathNavigator; if (that != null) { return IsDescendant(this.source, that.source); } return false; } public override IXmlSchemaInfo SchemaInfo { get { return source.SchemaInfo; } } public override bool CheckValidity(XmlSchemaSet schemas, ValidationEventHandler validationEventHandler) { XmlDocument ownerDocument; if (source.NodeType == XmlNodeType.Document) { ownerDocument = (XmlDocument)source; } else { ownerDocument = source.OwnerDocument; if (schemas != null) { throw new ArgumentException(Res.GetString(Res.XPathDocument_SchemaSetNotAllowed, null)); } } if (schemas == null && ownerDocument != null) { schemas = ownerDocument.Schemas; } if (schemas == null || schemas.Count == 0) { throw new InvalidOperationException(Res.GetString(Res.XmlDocument_NoSchemaInfo)); } DocumentSchemaValidator validator = new DocumentSchemaValidator(ownerDocument, schemas, validationEventHandler); validator.PsviAugmentation = false; return validator.Validate(source); } private static XmlNode OwnerNode(XmlNode node) { XmlNode parent = node.ParentNode; if (parent != null) { return parent; } XmlAttribute attribute = node as XmlAttribute; if (attribute != null) { return attribute.OwnerElement; } return null; } private static int GetDepth(XmlNode node) { int depth = 0; XmlNode owner = OwnerNode(node); while (owner != null) { depth++; owner = OwnerNode(owner); } return depth; } //Assuming that node1 and node2 are in the same level; Except when they are namespace nodes, they should have the same parent node //the returned value is node2's position corresponding to node1 private XmlNodeOrder Compare( XmlNode node1, XmlNode node2 ) { Debug.Assert( node1 != null ); Debug.Assert( node2 != null ); Debug.Assert( node1 != node2, "Should be handled by ComparePosition()" ); //Attribute nodes come before other children nodes except namespace nodes Debug.Assert( OwnerNode(node1) == OwnerNode(node2) ); if (node1.XPNodeType == XPathNodeType.Attribute) { if (node2.XPNodeType == XPathNodeType.Attribute) { XmlElement element = ((XmlAttribute)node1).OwnerElement; if (element.HasAttributes) { XmlAttributeCollection attributes = element.Attributes; for (int i = 0; i < attributes.Count; i++) { XmlAttribute attribute = attributes[i]; if (attribute == node1) { return XmlNodeOrder.Before; } else if (attribute == node2) { return XmlNodeOrder.After; } } } return XmlNodeOrder.Unknown; } else { return XmlNodeOrder.Before; } } if (node2.XPNodeType == XPathNodeType.Attribute) { return XmlNodeOrder.After; } //neither of the node is Namespace node or Attribute node XmlNode nextNode = node1.NextSibling; while ( nextNode != null && nextNode != node2 ) nextNode = nextNode.NextSibling; if ( nextNode == null ) //didn't meet node2 in the path to the end, thus it has to be in the front of node1 return XmlNodeOrder.After; else //met node2 in the path to the end, so node1 is at front return XmlNodeOrder.Before; } public override XmlNodeOrder ComparePosition(XPathNavigator other) { DocumentXPathNavigator that = other as DocumentXPathNavigator; if (that == null) { return XmlNodeOrder.Unknown; } this.CalibrateText(); that.CalibrateText(); if (this.source == that.source && this.namespaceParent == that.namespaceParent) { return XmlNodeOrder.Same; } if (this.namespaceParent != null || that.namespaceParent != null) { return base.ComparePosition(other); } XmlNode node1 = this.source; XmlNode node2 = that.source; XmlNode parent1 = OwnerNode(node1); XmlNode parent2 = OwnerNode(node2); if (parent1 == parent2) { if (parent1 == null) { return XmlNodeOrder.Unknown; } else { Debug.Assert(node1 != node2); return Compare(node1, node2); } } int depth1 = GetDepth(node1); int depth2 = GetDepth(node2); if (depth2 > depth1) { while (node2 != null && depth2 > depth1) { node2 = OwnerNode(node2); depth2--; } if (node1 == node2) { return XmlNodeOrder.Before; } parent2 = OwnerNode(node2); } else if (depth1 > depth2) { while (node1 != null && depth1 > depth2) { node1 = OwnerNode(node1); depth1--; } if (node1 == node2) { return XmlNodeOrder.After; } parent1 = OwnerNode(node1); } while (parent1 != null && parent2 != null) { if (parent1 == parent2) { Debug.Assert(node1 != node2); return Compare(node1, node2); } node1 = parent1; node2 = parent2; parent1 = OwnerNode(node1); parent2 = OwnerNode(node2); } return XmlNodeOrder.Unknown; } //the function just for XPathNodeList to enumerate current Node. XmlNode IHasXmlNode.GetNode() { return source; } public override XPathNodeIterator SelectDescendants( string localName, string namespaceURI, bool matchSelf ) { string nsAtom = document.NameTable.Get( namespaceURI ); if ( nsAtom == null || this.source.NodeType == XmlNodeType.Attribute ) return new DocumentXPathNodeIterator_Empty( this ); Debug.Assert( this.NodeType != XPathNodeType.Attribute && this.NodeType != XPathNodeType.Namespace && this.NodeType != XPathNodeType.All ); string localNameAtom = document.NameTable.Get( localName ); if ( localNameAtom == null ) return new DocumentXPathNodeIterator_Empty( this ); if ( localNameAtom.Length == 0 ) { if ( matchSelf ) return new DocumentXPathNodeIterator_ElemChildren_AndSelf_NoLocalName( this, nsAtom ); return new DocumentXPathNodeIterator_ElemChildren_NoLocalName( this, nsAtom ); } if ( matchSelf ) return new DocumentXPathNodeIterator_ElemChildren_AndSelf( this, localNameAtom, nsAtom ); return new DocumentXPathNodeIterator_ElemChildren( this, localNameAtom, nsAtom ); } public override XPathNodeIterator SelectDescendants( XPathNodeType nt, bool includeSelf ) { if ( nt == XPathNodeType.Element ) { XmlNodeType curNT = source.NodeType; if ( curNT != XmlNodeType.Document && curNT != XmlNodeType.Element ) { //only Document, Entity, Element node can have Element node as children ( descendant ) //entity nodes should be invisible to XPath data model return new DocumentXPathNodeIterator_Empty( this ); } if ( includeSelf ) return new DocumentXPathNodeIterator_AllElemChildren_AndSelf( this ); return new DocumentXPathNodeIterator_AllElemChildren( this ); } return base.SelectDescendants( nt, includeSelf ); } public override bool CanEdit { get { return true; } } public override XmlWriter PrependChild() { switch (source.NodeType) { case XmlNodeType.Element: case XmlNodeType.Document: case XmlNodeType.DocumentFragment: break; default: throw new InvalidOperationException(Res.GetString(Res.Xpn_BadPosition)); } DocumentXmlWriter writer = new DocumentXmlWriter(DocumentXmlWriterType.PrependChild, source, document); writer.NamespaceManager = GetNamespaceManager(source, document); return new XmlWellFormedWriter(writer, writer.Settings); } public override XmlWriter AppendChild() { switch (source.NodeType) { case XmlNodeType.Element: case XmlNodeType.Document: case XmlNodeType.DocumentFragment: break; default: throw new InvalidOperationException(Res.GetString(Res.Xpn_BadPosition)); } DocumentXmlWriter writer = new DocumentXmlWriter(DocumentXmlWriterType.AppendChild, source, document); writer.NamespaceManager = GetNamespaceManager(source, document); return new XmlWellFormedWriter(writer, writer.Settings); } public override XmlWriter InsertAfter() { XmlNode node = source; switch (node.NodeType) { case XmlNodeType.Attribute: case XmlNodeType.Document: case XmlNodeType.DocumentFragment: throw new InvalidOperationException(Res.GetString(Res.Xpn_BadPosition)); case XmlNodeType.Text: case XmlNodeType.CDATA: case XmlNodeType.SignificantWhitespace: case XmlNodeType.Whitespace: node = TextEnd(node); break; default: break; } DocumentXmlWriter writer = new DocumentXmlWriter(DocumentXmlWriterType.InsertSiblingAfter, node, document); writer.NamespaceManager = GetNamespaceManager(node.ParentNode, document); return new XmlWellFormedWriter(writer, writer.Settings); } public override XmlWriter InsertBefore() { switch (source.NodeType) { case XmlNodeType.Attribute: case XmlNodeType.Document: case XmlNodeType.DocumentFragment: throw new InvalidOperationException(Res.GetString(Res.Xpn_BadPosition)); case XmlNodeType.Text: case XmlNodeType.CDATA: case XmlNodeType.SignificantWhitespace: case XmlNodeType.Whitespace: CalibrateText(); break; default: break; } DocumentXmlWriter writer = new DocumentXmlWriter(DocumentXmlWriterType.InsertSiblingBefore, source, document); writer.NamespaceManager = GetNamespaceManager(source.ParentNode, document); return new XmlWellFormedWriter(writer, writer.Settings); } public override XmlWriter CreateAttributes() { if (source.NodeType != XmlNodeType.Element) { throw new InvalidOperationException(Res.GetString(Res.Xpn_BadPosition)); } DocumentXmlWriter writer = new DocumentXmlWriter(DocumentXmlWriterType.AppendAttribute, source, document); writer.NamespaceManager = GetNamespaceManager(source, document); return new XmlWellFormedWriter(writer, writer.Settings); } public override XmlWriter ReplaceRange(XPathNavigator lastSiblingToReplace) { DocumentXPathNavigator that = lastSiblingToReplace as DocumentXPathNavigator; if (that == null) { if (lastSiblingToReplace == null) { throw new ArgumentNullException("lastSiblingToReplace"); } else { throw new NotSupportedException(); } } this.CalibrateText(); that.CalibrateText(); XmlNode node = this.source; XmlNode end = that.source; if (node == end) { switch (node.NodeType) { case XmlNodeType.Attribute: case XmlNodeType.Document: case XmlNodeType.DocumentFragment: throw new InvalidOperationException(Res.GetString(Res.Xpn_BadPosition)); case XmlNodeType.Text: case XmlNodeType.CDATA: case XmlNodeType.SignificantWhitespace: case XmlNodeType.Whitespace: end = that.TextEnd(end); break; default: break; } } else { if (end.IsText) { end = that.TextEnd(end); } if (!IsFollowingSibling(node, end)) { throw new InvalidOperationException(Res.GetString(Res.Xpn_BadPosition)); } } DocumentXmlWriter writer = new DocumentXmlWriter(DocumentXmlWriterType.ReplaceToFollowingSibling, node, document); writer.NamespaceManager = GetNamespaceManager(node.ParentNode, document); writer.Navigator = this; writer.EndNode = end; return new XmlWellFormedWriter(writer, writer.Settings); } public override void DeleteRange(XPathNavigator lastSiblingToDelete) { DocumentXPathNavigator that = lastSiblingToDelete as DocumentXPathNavigator; if (that == null) { if (lastSiblingToDelete == null) { throw new ArgumentNullException("lastSiblingToDelete"); } else { throw new NotSupportedException(); } } this.CalibrateText(); that.CalibrateText(); XmlNode node = this.source; XmlNode end = that.source; if (node == end) { switch (node.NodeType) { case XmlNodeType.Attribute: XmlAttribute attribute = (XmlAttribute)node; if (attribute.IsNamespace) { goto default; } XmlNode parent = OwnerNode(attribute); DeleteAttribute(attribute, attributeIndex); if (parent != null) { ResetPosition(parent); } break; case XmlNodeType.Text: case XmlNodeType.CDATA: case XmlNodeType.SignificantWhitespace: case XmlNodeType.Whitespace: end = that.TextEnd(end); goto case XmlNodeType.Element; case XmlNodeType.Element: case XmlNodeType.ProcessingInstruction: case XmlNodeType.Comment: parent = OwnerNode(node); DeleteToFollowingSibling(node, end); if (parent != null) { ResetPosition(parent); } break; default: throw new InvalidOperationException(Res.GetString(Res.Xpn_BadPosition)); } } else { if (end.IsText) { end = that.TextEnd(end); } if (!IsFollowingSibling(node, end)) { throw new InvalidOperationException(Res.GetString(Res.Xpn_BadPosition)); } XmlNode parent = OwnerNode(node); DeleteToFollowingSibling(node, end); if (parent != null) { ResetPosition(parent); } } } public override void DeleteSelf() { XmlNode node = source; XmlNode end = node; switch (node.NodeType) { case XmlNodeType.Attribute: XmlAttribute attribute = (XmlAttribute)node; if (attribute.IsNamespace) { goto default; } XmlNode parent = OwnerNode(attribute); DeleteAttribute(attribute, attributeIndex); if (parent != null) { ResetPosition(parent); } break; case XmlNodeType.Text: case XmlNodeType.CDATA: case XmlNodeType.SignificantWhitespace: case XmlNodeType.Whitespace: CalibrateText(); node = source; end = TextEnd(node); goto case XmlNodeType.Element; case XmlNodeType.Element: case XmlNodeType.ProcessingInstruction: case XmlNodeType.Comment: parent = OwnerNode(node); DeleteToFollowingSibling(node, end); if (parent != null) { ResetPosition(parent); } break; default: throw new InvalidOperationException(Res.GetString(Res.Xpn_BadPosition)); } } private static void DeleteAttribute(XmlAttribute attribute, int index) { XmlAttributeCollection attributes; if (!CheckAttributePosition(attribute, out attributes, index) && !ResetAttributePosition(attribute, attributes, out index)) { throw new InvalidOperationException(Res.GetString(Res.Xpn_MissingParent)); } if (attribute.IsReadOnly) { throw new InvalidOperationException(Res.GetString(Res.Xdom_Node_Modify_ReadOnly)); } attributes.RemoveAt(index); } internal static void DeleteToFollowingSibling(XmlNode node, XmlNode end) { XmlNode parent = node.ParentNode; if (parent == null) { throw new InvalidOperationException(Res.GetString(Res.Xpn_MissingParent)); } if (node.IsReadOnly || end.IsReadOnly) { throw new InvalidOperationException(Res.GetString(Res.Xdom_Node_Modify_ReadOnly)); } while (node != end) { XmlNode temp = node; node = node.NextSibling; parent.RemoveChild(temp); } parent.RemoveChild(node); } private static XmlNamespaceManager GetNamespaceManager(XmlNode node, XmlDocument document) { XmlNamespaceManager namespaceManager = new XmlNamespaceManager(document.NameTable); Listelements = new List (); while (node != null) { XmlElement element = node as XmlElement; if (element != null && element.HasAttributes) { elements.Add(element); } node = node.ParentNode; } for (int i = elements.Count - 1; i >= 0; i--) { namespaceManager.PushScope(); XmlAttributeCollection attributes = elements[i].Attributes; for (int j = 0; j < attributes.Count; j++) { XmlAttribute attribute = attributes[j]; if (attribute.IsNamespace) { string prefix = attribute.Prefix.Length == 0 ? string.Empty : attribute.LocalName; namespaceManager.AddNamespace(prefix, attribute.Value); } } } return namespaceManager; } internal void ResetPosition(XmlNode node) { Debug.Assert(node != null, "Undefined navigator position"); Debug.Assert(node == document || node.OwnerDocument == document, "Navigator switched documents"); source = node; XmlAttribute attribute = node as XmlAttribute; if (attribute != null) { XmlElement element = attribute.OwnerElement; if (element != null) { ResetAttributePosition(attribute, element.Attributes, out attributeIndex); if (attribute.IsNamespace) { namespaceParent = element; } } } } private static bool ResetAttributePosition(XmlAttribute attribute, XmlAttributeCollection attributes, out int index) { if (attributes != null) { for (int i = 0; i < attributes.Count; i++) { if (attribute == attributes[i]) { index = i; return true; } } } index = 0; return false; } private static bool CheckAttributePosition(XmlAttribute attribute, out XmlAttributeCollection attributes, int index) { XmlElement element = attribute.OwnerElement; if (element != null) { attributes = element.Attributes; if (index >= 0 && index < attributes.Count && attribute == attributes[index]) { return true; } } else { attributes = null; } return false; } private void CalibrateText() { XmlNode text = PreviousText(source); while (text != null) { ResetPosition(text); text = PreviousText(text); } } private XmlNode ParentNode(XmlNode node) { XmlNode parent = node.ParentNode; if (!document.HasEntityReferences) { return parent; } return ParentNodeTail(parent); } private XmlNode ParentNodeTail(XmlNode parent) { while (parent != null && parent.NodeType == XmlNodeType.EntityReference) { parent = parent.ParentNode; } return parent; } private XmlNode FirstChild(XmlNode node) { XmlNode child = node.FirstChild; if (!document.HasEntityReferences) { return child; } return FirstChildTail(child); } private XmlNode FirstChildTail(XmlNode child) { while (child != null && child.NodeType == XmlNodeType.EntityReference) { child = child.FirstChild; } return child; } private XmlNode NextSibling(XmlNode node) { XmlNode sibling = node.NextSibling; if (!document.HasEntityReferences) { return sibling; } return NextSiblingTail(node, sibling); } private XmlNode NextSiblingTail(XmlNode node, XmlNode sibling) { while (sibling == null) { node = node.ParentNode; if (node == null || node.NodeType != XmlNodeType.EntityReference) { return null; } sibling = node.NextSibling; } while (sibling != null && sibling.NodeType == XmlNodeType.EntityReference) { sibling = sibling.FirstChild; } return sibling; } private XmlNode PreviousSibling(XmlNode node) { XmlNode sibling = node.PreviousSibling; if (!document.HasEntityReferences) { return sibling; } return PreviousSiblingTail(node, sibling); } private XmlNode PreviousSiblingTail(XmlNode node, XmlNode sibling) { while (sibling == null) { node = node.ParentNode; if (node == null || node.NodeType != XmlNodeType.EntityReference) { return null; } sibling = node.PreviousSibling; } while (sibling != null && sibling.NodeType == XmlNodeType.EntityReference) { sibling = sibling.LastChild; } return sibling; } private XmlNode PreviousText(XmlNode node) { XmlNode text = node.PreviousText; if (!document.HasEntityReferences) { return text; } return PreviousTextTail(node, text); } private XmlNode PreviousTextTail(XmlNode node, XmlNode text) { if (text != null) { return text; } if (!node.IsText) { return null; } XmlNode sibling = node.PreviousSibling; while (sibling == null) { node = node.ParentNode; if (node == null || node.NodeType != XmlNodeType.EntityReference) { return null; } sibling = node.PreviousSibling; } while (sibling != null) { switch (sibling.NodeType) { case XmlNodeType.EntityReference: sibling = sibling.LastChild; break; case XmlNodeType.Text: case XmlNodeType.CDATA: case XmlNodeType.Whitespace: case XmlNodeType.SignificantWhitespace: return sibling; default: return null; } } return null; } internal static bool IsFollowingSibling(XmlNode left, XmlNode right) { for (;;) { left = left.NextSibling; if (left == null) { break; } if (left == right) { return true; } } return false; } private static bool IsDescendant(XmlNode top, XmlNode bottom) { for (;;) { XmlNode parent = bottom.ParentNode; if (parent == null) { XmlAttribute attribute = bottom as XmlAttribute; if (attribute == null) { break; } parent = attribute.OwnerElement; if (parent == null) { break; } } bottom = parent; if (top == bottom) { return true; } } return false; } private static bool IsValidChild(XmlNode parent, XmlNode child) { switch (parent.NodeType) { case XmlNodeType.Element: return true; case XmlNodeType.DocumentFragment: switch (child.NodeType) { case XmlNodeType.Element: case XmlNodeType.Text: case XmlNodeType.CDATA: case XmlNodeType.ProcessingInstruction: case XmlNodeType.Comment: case XmlNodeType.Whitespace: case XmlNodeType.SignificantWhitespace: return true; } break; case XmlNodeType.Document: switch (child.NodeType) { case XmlNodeType.Element: case XmlNodeType.ProcessingInstruction: case XmlNodeType.Comment: return true; } break; default: break; } return false; } private XmlNode TextStart(XmlNode node) { XmlNode start; do { start = node; node = PreviousSibling(node); } while (node != null && node.IsText); return start; } private XmlNode TextEnd(XmlNode node) { XmlNode end; do { end = node; node = NextSibling(node); } while (node != null && node.IsText); return end; } } // An iterator that matches no nodes internal sealed class DocumentXPathNodeIterator_Empty : XPathNodeIterator { private XPathNavigator nav; internal DocumentXPathNodeIterator_Empty( DocumentXPathNavigator nav ) { this.nav = nav.Clone(); } internal DocumentXPathNodeIterator_Empty( DocumentXPathNodeIterator_Empty other ) { this.nav = other.nav.Clone(); } public override XPathNodeIterator Clone() { return new DocumentXPathNodeIterator_Empty( this ); } public override bool MoveNext() { return false; } public override XPathNavigator Current { get { return nav; } } public override int CurrentPosition { get { return 0; } } public override int Count { get { return 0; } } } // An iterator that can match any child elements that match the Match condition (overrided in the derived class) internal abstract class DocumentXPathNodeIterator_ElemDescendants : XPathNodeIterator { private DocumentXPathNavigator nav; private int level; private int position; internal DocumentXPathNodeIterator_ElemDescendants( DocumentXPathNavigator nav ) { this.nav = (DocumentXPathNavigator)(nav.Clone()); this.level = 0; this.position = 0; } internal DocumentXPathNodeIterator_ElemDescendants( DocumentXPathNodeIterator_ElemDescendants other ) { this.nav = (DocumentXPathNavigator)(other.nav.Clone()); this.level = other.level; this.position = other.position; } protected abstract bool Match( XmlNode node ); public override XPathNavigator Current { get { return nav; } } public override int CurrentPosition { get { return position; } } protected void SetPosition( int pos ) { position = pos; } public override bool MoveNext() { for (;;) { if (nav.MoveToFirstChild()) { level++; } else { if (level == 0) { return false; } while (!nav.MoveToNext()) { level--; if (level == 0) { return false; } if (!nav.MoveToParent()) { return false; } } } XmlNode node = (XmlNode)nav.UnderlyingObject; if (node.NodeType == XmlNodeType.Element && Match(node)) { position++; return true; } } } } // Iterate over all element children irrespective of the localName and namespace internal class DocumentXPathNodeIterator_AllElemChildren : DocumentXPathNodeIterator_ElemDescendants { internal DocumentXPathNodeIterator_AllElemChildren( DocumentXPathNavigator nav ) : base( nav ) { Debug.Assert( ((XmlNode)nav.UnderlyingObject).NodeType != XmlNodeType.Attribute ); } internal DocumentXPathNodeIterator_AllElemChildren( DocumentXPathNodeIterator_AllElemChildren other ) : base( other ) { } public override XPathNodeIterator Clone() { return new DocumentXPathNodeIterator_AllElemChildren( this ); } protected override bool Match( XmlNode node ) { Debug.Assert( node != null ); return ( node.NodeType == XmlNodeType.Element ); } } // Iterate over all element children irrespective of the localName and namespace, include the self node when testing for localName/ns internal sealed class DocumentXPathNodeIterator_AllElemChildren_AndSelf : DocumentXPathNodeIterator_AllElemChildren { internal DocumentXPathNodeIterator_AllElemChildren_AndSelf( DocumentXPathNavigator nav ) : base( nav ) { } internal DocumentXPathNodeIterator_AllElemChildren_AndSelf( DocumentXPathNodeIterator_AllElemChildren_AndSelf other ) : base( other ) { } public override XPathNodeIterator Clone() { return new DocumentXPathNodeIterator_AllElemChildren_AndSelf( this ); } public override bool MoveNext() { if( CurrentPosition == 0 ) { DocumentXPathNavigator nav = (DocumentXPathNavigator)this.Current; XmlNode node = (XmlNode)nav.UnderlyingObject; if ( node.NodeType == XmlNodeType.Element && Match( node ) ) { SetPosition( 1 ); return true; } } return base.MoveNext(); } } // Iterate over all element children that have a given namespace but irrespective of the localName internal class DocumentXPathNodeIterator_ElemChildren_NoLocalName : DocumentXPathNodeIterator_ElemDescendants { private string nsAtom; internal DocumentXPathNodeIterator_ElemChildren_NoLocalName( DocumentXPathNavigator nav, string nsAtom ) : base( nav ) { Debug.Assert( ((XmlNode)nav.UnderlyingObject).NodeType != XmlNodeType.Attribute ); Debug.Assert( Ref.Equal(nav.NameTable.Get( nsAtom ), nsAtom) ); this.nsAtom = nsAtom; } internal DocumentXPathNodeIterator_ElemChildren_NoLocalName( DocumentXPathNodeIterator_ElemChildren_NoLocalName other ) : base( other ) { this.nsAtom = other.nsAtom; } public override XPathNodeIterator Clone() { return new DocumentXPathNodeIterator_ElemChildren_NoLocalName( this ); } protected override bool Match( XmlNode node ) { Debug.Assert( node != null ); Debug.Assert( node.NodeType == XmlNodeType.Element ); return Ref.Equal(node.NamespaceURI, nsAtom); } } // Iterate over all element children that have a given namespace but irrespective of the localName, include self node when checking for ns internal sealed class DocumentXPathNodeIterator_ElemChildren_AndSelf_NoLocalName : DocumentXPathNodeIterator_ElemChildren_NoLocalName { internal DocumentXPathNodeIterator_ElemChildren_AndSelf_NoLocalName( DocumentXPathNavigator nav, string nsAtom ) : base( nav, nsAtom ) { } internal DocumentXPathNodeIterator_ElemChildren_AndSelf_NoLocalName( DocumentXPathNodeIterator_ElemChildren_AndSelf_NoLocalName other ) : base( other ) { } public override XPathNodeIterator Clone() { return new DocumentXPathNodeIterator_ElemChildren_AndSelf_NoLocalName( this ); } public override bool MoveNext() { if( CurrentPosition == 0 ) { DocumentXPathNavigator nav = (DocumentXPathNavigator)this.Current; XmlNode node = (XmlNode)nav.UnderlyingObject; if ( node.NodeType == XmlNodeType.Element && Match( node ) ) { SetPosition( 1 ); return true; } } return base.MoveNext(); } } // Iterate over all element children that have a given name and namespace internal class DocumentXPathNodeIterator_ElemChildren : DocumentXPathNodeIterator_ElemDescendants { protected string localNameAtom; protected string nsAtom; internal DocumentXPathNodeIterator_ElemChildren( DocumentXPathNavigator nav, string localNameAtom, string nsAtom ) : base( nav ) { Debug.Assert( ((XmlNode)nav.UnderlyingObject).NodeType != XmlNodeType.Attribute ); Debug.Assert( Ref.Equal(nav.NameTable.Get( localNameAtom ), localNameAtom) ); Debug.Assert( Ref.Equal(nav.NameTable.Get( nsAtom ), nsAtom) ); Debug.Assert( localNameAtom.Length > 0 ); // Use DocumentXPathNodeIterator_ElemChildren_NoLocalName class for special magic value of localNameAtom this.localNameAtom = localNameAtom; this.nsAtom = nsAtom; } internal DocumentXPathNodeIterator_ElemChildren( DocumentXPathNodeIterator_ElemChildren other ) : base( other ) { this.localNameAtom = other.localNameAtom; this.nsAtom = other.nsAtom; } public override XPathNodeIterator Clone() { return new DocumentXPathNodeIterator_ElemChildren( this ); } protected override bool Match( XmlNode node ) { Debug.Assert( node != null ); Debug.Assert( node.NodeType == XmlNodeType.Element ); return Ref.Equal(node.LocalName, localNameAtom) && Ref.Equal(node.NamespaceURI, nsAtom); } } // Iterate over all elem children and itself and check for the given localName (including the magic value "") and namespace internal sealed class DocumentXPathNodeIterator_ElemChildren_AndSelf : DocumentXPathNodeIterator_ElemChildren { internal DocumentXPathNodeIterator_ElemChildren_AndSelf( DocumentXPathNavigator nav, string localNameAtom, string nsAtom ) : base( nav, localNameAtom, nsAtom ) { Debug.Assert( localNameAtom.Length > 0 ); // Use DocumentXPathNodeIterator_ElemChildren_AndSelf_NoLocalName if localName == String.Empty } internal DocumentXPathNodeIterator_ElemChildren_AndSelf( DocumentXPathNodeIterator_ElemChildren_AndSelf other ) : base( other ) { } public override XPathNodeIterator Clone() { return new DocumentXPathNodeIterator_ElemChildren_AndSelf( this ); } public override bool MoveNext() { if( CurrentPosition == 0 ) { DocumentXPathNavigator nav = (DocumentXPathNavigator)this.Current; XmlNode node = (XmlNode)nav.UnderlyingObject; if ( node.NodeType == XmlNodeType.Element && Match( node ) ) { SetPosition( 1 ); return true; } } return base.MoveNext(); } } } // 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
- OptimalTextSource.cs
- ZeroOpNode.cs
- DBCommandBuilder.cs
- BuildManager.cs
- EventHandlersDesigner.cs
- DbgUtil.cs
- ChooseAction.cs
- RelationalExpressions.cs
- HebrewNumber.cs
- Transform3DCollection.cs
- XMLSyntaxException.cs
- DesigntimeLicenseContextSerializer.cs
- FamilyCollection.cs
- XmlCharacterData.cs
- RtfFormatStack.cs
- TrackingProfileSerializer.cs
- HttpRequestWrapper.cs
- RightsManagementLicense.cs
- SByte.cs
- DataControlCommands.cs
- TextParagraphProperties.cs
- GlyphRun.cs
- WsatStrings.cs
- AsyncResult.cs
- ValueType.cs
- SmiConnection.cs
- RadialGradientBrush.cs
- Helpers.cs
- DbException.cs
- AVElementHelper.cs
- InfoCardRSAPKCS1SignatureFormatter.cs
- BaseDataListActionList.cs
- DriveNotFoundException.cs
- CorrelationManager.cs
- ButtonPopupAdapter.cs
- DiagnosticsConfiguration.cs
- BitmapEffectInput.cs
- DefaultPrintController.cs
- AnnotationResource.cs
- WebServiceClientProxyGenerator.cs
- IIS7UserPrincipal.cs
- Optimizer.cs
- Oid.cs
- DefaultMergeHelper.cs
- ReflectionHelper.cs
- BrowserCapabilitiesFactoryBase.cs
- MenuScrollingVisibilityConverter.cs
- CodeNamespaceCollection.cs
- MessageEnumerator.cs
- WebPartConnectionsDisconnectVerb.cs
- XmlSchemaCollection.cs
- UnknownBitmapEncoder.cs
- MonikerBuilder.cs
- _UncName.cs
- TransformGroup.cs
- ContractListAdapter.cs
- CreationContext.cs
- AuthenticationService.cs
- XhtmlBasicImageAdapter.cs
- FontDifferentiator.cs
- QuinticEase.cs
- ElementHostPropertyMap.cs
- AutomationElementIdentifiers.cs
- StylusButtonCollection.cs
- PointCollection.cs
- WebPartConnectVerb.cs
- CfgParser.cs
- SpellerError.cs
- Switch.cs
- SettingsPropertyValue.cs
- GcSettings.cs
- Hashtable.cs
- SqlDataSourceEnumerator.cs
- CustomPopupPlacement.cs
- IsolatedStorageFile.cs
- InfoCardRSAOAEPKeyExchangeDeformatter.cs
- ActivityDesigner.cs
- PasswordPropertyTextAttribute.cs
- SmuggledIUnknown.cs
- FormViewUpdatedEventArgs.cs
- AssemblySettingAttributes.cs
- StatementContext.cs
- IndexOutOfRangeException.cs
- TypeInitializationException.cs
- MessageBox.cs
- PartManifestEntry.cs
- SizeF.cs
- COM2Enum.cs
- SecurityKeyType.cs
- CultureInfoConverter.cs
- OpenTypeLayout.cs
- DataSysAttribute.cs
- XPathNodePointer.cs
- StackSpiller.cs
- ColumnHeader.cs
- ObjectHandle.cs
- HttpCapabilitiesSectionHandler.cs
- WindowProviderWrapper.cs
- ToolStripItemImageRenderEventArgs.cs
- DocumentPageHost.cs