+2004-09-06 Atsushi Enomoto <atsushi@ximian.com>
+
+ * XPathDocument2.cs, XPathDocument2Editable.cs:
+ Redesigned API. Child node list should not be required (it also
+ harms performance). Reduced extraneous methods for XPathNavigator
+ / XPathEditableNavigator implementation support.
+ * XPathEditableDocument.cs : event registration was missing (due to
+ XPathDocument changes, it might not be required anymore though).
+ * XPathNavigatorReader.cs :
+ Namespace nodes were not handled correctly.
+ EOF handling was incorrect.
+ Reduced extraneous clone from MoveTo/GetAttribute(int) and
+
2004-09-01 Atsushi Enomoto <atsushi@ximian.com>
* XPathNavigatorReader.cs : on GetAttributeNavigator(int), namespace
\r
public abstract XPathNodeType NodeType { get; }\r
\r
- public abstract XomNode GetChild (int position);\r
-\r
public abstract int ChildCount { get; }\r
\r
public virtual XomNode FirstChild { get { return null; } }\r
get {\r
StringWriter sw = new StringWriter ();\r
XmlTextWriter xtw = new XmlTextWriter (sw);\r
- for (int i = 0; i < ChildCount; i++)\r
- GetChild (i).WriteTo (xtw);\r
+ for (XomNode n = FirstChild; n != null; n = n.NextSibling)\r
+ n.WriteTo (xtw);\r
return sw.ToString ();\r
}\r
}\r
\r
public abstract class XomParentNode : XomNode\r
{\r
- ArrayList children = new ArrayList ();\r
XomNode firstChild;\r
XomNode lastChild;\r
+ int childCount;\r
\r
public void ReadNode (XmlReader reader, XmlSpace space)\r
{\r
\r
public void AppendChild (XomNode child)\r
{\r
- child.SetParent (this);\r
- children.Add (child);\r
- if (firstChild == null)\r
- firstChild = lastChild = child;\r
- else {\r
- child.SetPreviousSibling (lastChild);\r
- lastChild = child;\r
- }\r
+ InsertBefore (child, null);\r
}\r
\r
public void InsertBefore (XomNode child, XomNode nextNode)\r
{\r
- int pos = children.IndexOf (nextNode);\r
- if (pos < 0)\r
- throw new ArgumentException ("Argument nextNode is not a child of this node.");\r
- InsertChild (child, pos);\r
+ if (child.Parent != null)\r
+ throw new InvalidOperationException ("The child already has a parent.");\r
+ if (nextNode == null) {\r
+ child.SetParent (this);\r
+ if (firstChild == null)\r
+ firstChild = lastChild = child;\r
+ else {\r
+ child.SetPreviousSibling (lastChild);\r
+ lastChild = child;\r
+ }\r
+ } else {\r
+ if (nextNode.Parent != this)\r
+ throw new ArgumentException ("Argument nextNode is not a child of this node.");\r
+ child.SetNextSibling (nextNode);\r
+ }\r
+ childCount++;\r
}\r
\r
public abstract void Clear ();\r
get { return lastChild; }\r
}\r
\r
- public override XomNode GetChild (int position)\r
- {\r
- if (position > children.Count)\r
- return null;\r
- return children [position] as XomNode;\r
- }\r
-\r
public override int ChildCount {\r
- get { return children.Count; }\r
+ get { return childCount; }\r
}\r
\r
internal void ClearChildren ()\r
{\r
- while (children.Count > 0)\r
- RemoveChildAt (0);\r
- }\r
-\r
- public void InsertChild (XomNode child, int position)\r
- {\r
- XomNode n = children [position] as XomNode;\r
- child.SetNextSibling (n);\r
- children.Insert (position, position);\r
- }\r
-\r
- public void RemoveChildAt (int index)\r
- {\r
- RemoveChild (children [index] as XomNode);\r
- }\r
-\r
- public void ReplaceChildAt (int index,\r
- XomNode newChild)\r
- {\r
- XomNode n = children [index] as XomNode;\r
- newChild.SetNextSibling (n);\r
- RemoveChild (n);\r
+ firstChild = lastChild = null;\r
+ childCount = 0;\r
}\r
\r
public void RemoveChild (XomNode child)\r
{\r
- children.Remove (child);\r
+ if (child == firstChild)\r
+ firstChild = child.NextSibling;\r
+ if (child == lastChild)\r
+ lastChild = child.PreviousSibling;\r
child.RemoveItself ();\r
+ childCount--;\r
}\r
\r
public override string Value {\r
\r
internal override void BuildValue (StringBuilder sb)\r
{\r
- int count = ChildCount;\r
- for (int i = 0; i < count; i++)\r
- GetChild (i).BuildValue (sb);\r
+ for (XomNode n = FirstChild; n != null; n = n.NextSibling)\r
+ n.BuildValue (sb);\r
}\r
}\r
\r
\r
public override void WriteTo (XmlWriter writer)\r
{\r
- int count = ChildCount;\r
- for (int i = 0; i < count; i++)\r
- GetChild (i).WriteTo (writer);\r
+ for (XomNode n = FirstChild; n != null; n = n.NextSibling)\r
+ n.WriteTo (writer);\r
}\r
\r
public XomElement GetIdenticalNode (string id)\r
attributes.Add (attr);\r
}\r
\r
+/*\r
public void UpdateAttribute (XomAttribute attr)\r
{\r
if (attr.Parent != null)\r
attr.SetParent (this);\r
attributes.Add (attr);\r
}\r
+*/\r
\r
public XomAttribute GetAttribute (int index)\r
{\r
a.WriteTo (writer);\r
}\r
\r
- int count = ChildCount;\r
- for (int i = 0; i < count; i++)\r
- GetChild (i).WriteTo (writer);\r
+ for (XomNode n = FirstChild; n != null; n = n.NextSibling)\r
+ n.WriteTo (writer);\r
\r
writer.WriteEndElement ();\r
}\r
get { return XPathNodeType.Attribute; }\r
}\r
\r
- public override XomNode GetChild (int index)\r
- {\r
- return null;\r
- }\r
-\r
public override int ChildCount { get { return 0; } }\r
\r
public override string Value {\r
get { return 0; }\r
}\r
\r
- public override XomNode GetChild (int index)\r
- {\r
- return null;\r
- }\r
-\r
public override string LocalName {\r
get { return qname.LocalName; }\r
}\r
sb.Append (value);\r
}\r
\r
- public override XomNode GetChild (int index)\r
- {\r
- return null;\r
- }\r
-\r
public override int ChildCount { get { return 0; } }\r
\r
public override void WriteTo (XmlWriter writer)\r
sb.Append (value);\r
}\r
\r
- public override XomNode GetChild (int index)\r
- {\r
- return null;\r
- }\r
-\r
public override int ChildCount { get { return 0; } }\r
\r
public override void WriteTo (XmlWriter writer)\r
sb.Append (value);\r
}\r
\r
- public override XomNode GetChild (int index)\r
- {\r
- return null;\r
- }\r
-\r
public override int ChildCount { get { return 0; } }\r
\r
public override void WriteTo (XmlWriter writer)\r
sb.Append (value);\r
}\r
\r
- public override XomNode GetChild (int index)\r
- {\r
- return null;\r
- }\r
-\r
public override int ChildCount { get { return 0; } }\r
\r
public override void WriteTo (XmlWriter writer)\r
sb.Append (value);\r
}\r
\r
- public override XomNode GetChild (int index)\r
- {\r
- return null;\r
- }\r
-\r
public override int ChildCount { get { return 0; } }\r
\r
public override void WriteTo (XmlWriter writer)\r
if (rem != null) {
if (rem.RemovedNode.NodeType == XPathNodeType.Attribute) {
XomElement el = (XomElement) rem.OwnerNode;
- el.UpdateAttribute ((XomAttribute) rem.RemovedNode);
+ el.AppendAttribute ((XomAttribute) rem.RemovedNode);
}
else
rem.OwnerNode.InsertBefore (rem.RemovedNode, rem.NextSibling);
}
AttributeUpdate2 au = changes [i] as AttributeUpdate2;
if (au != null) {
+ au.Element.RemoveAttribute (au.NewAttribute);
if (au.OldAttribute != null)
- au.Element.UpdateAttribute (au.OldAttribute);
- else
- au.Element.RemoveAttribute (au.NewAttribute);
+ au.Element.AppendAttribute (au.OldAttribute);
continue;
}
}
if (state != WriteState.Attribute || element == null)
throw new InvalidOperationException ("Current state is not inside attribute. Cannot close attribute.");
XomAttribute old = element.GetAttribute (attribute.LocalName, attribute.Namespace);
- element.UpdateAttribute (attribute);
+ element.AppendAttribute (attribute);
document.AttributeUpdate2 (element, old, attribute);
attribute = null;
state = WriteState.Content;
if (state != WriteState.Attribute)
throw new InvalidOperationException ("Current state is not inside attribute. Cannot close attribute.");
XomAttribute old = element.GetAttribute (attribute.LocalName, attribute.Namespace);
- element.UpdateAttribute (attribute);
+ element.AppendAttribute (attribute);
document.AttributeUpdate2 (element, old, attribute);
attribute = null;
state = WriteState.Content;
{
XomNode n = ((IHasXomNode) navigator).GetNode ();
int count = n.ChildCount;
- for (int i = 0; i < count; i++)
- document.DeleteNode (n.GetChild (i));
+ while (n.FirstChild != null)
+ document.DeleteNode (n.FirstChild);
XmlWriter w = document.CreateInsertionWriter (n, null);
// FIXME: Hmm, it does not look like using it.
w.WriteFromObject (value);
{
if (attribute != null)
attribute.Value += text;
- else
- current.AppendChild (current.OwnerDocument.CreateTextNode (text));
+ else {
+ XmlText t = current.OwnerDocument.CreateTextNode (text);
+ current.AppendChild (t);
+ document.AppendChild (current, t);
+ }
}
public override void WriteWhitespace (string text)
return XmlNodeType.None;\r
if (endElement)\r
return XmlNodeType.EndElement;\r
- if (attributeValueConsumed) {\r
- switch (current.NodeType) {\r
- case XPathNodeType.Whitespace:\r
- return XmlNodeType.Whitespace;\r
- case XPathNodeType.SignificantWhitespace:\r
- return XmlNodeType.SignificantWhitespace;\r
- default:\r
- return XmlNodeType.Text;\r
- }\r
- }\r
+ if (attributeValueConsumed)\r
+ // Is there any way to get other kind of nodes than Text?\r
+ return XmlNodeType.Text;\r
\r
switch (current.NodeType) {\r
case XPathNodeType.Namespace:\r
}\r
\r
public override string Name {\r
- get { return eof ? String.Empty : current.Name; }\r
+ get {\r
+ if (eof)\r
+ return String.Empty;\r
+ else if (current.NodeType == XPathNodeType.Namespace)\r
+ return current.Name == String.Empty ? "xmlns" : "xmlns:" + current.Name;\r
+ else\r
+ return current.Name;\r
+ }\r
}\r
\r
public override string LocalName {\r
- get { return eof ? String.Empty : current.LocalName; }\r
+ get {\r
+ if (eof)\r
+ return String.Empty;\r
+ else if (current.NodeType == XPathNodeType.Namespace && current.LocalName == String.Empty)\r
+ return "xmlns";\r
+ else\r
+ return current.LocalName;\r
+ }\r
}\r
\r
public override string NamespaceURI {\r
- get { return eof ? String.Empty : current.NamespaceURI; }\r
+ get {\r
+ if (eof)\r
+ return String.Empty;\r
+ else if (current.NodeType == XPathNodeType.Namespace)\r
+ return XmlNamespaceManager.XmlnsXmlns;\r
+ else\r
+ return current.NamespaceURI;\r
+ }\r
}\r
\r
public override string Prefix {\r
- get { return eof ? String.Empty : current.Prefix; }\r
+ get {\r
+ if (eof)\r
+ return String.Empty;\r
+ else if (current.NodeType == XPathNodeType.Namespace && current.LocalName != String.Empty)\r
+ return "xmlns";\r
+ else\r
+ return current.Prefix;\r
+ }\r
}\r
\r
public override bool HasValue {\r
return count;\r
}\r
\r
- private XPathNavigator GetAttributeNavigator (int i)\r
+ private bool MoveToAttributeNavigator (int i)\r
{\r
- XPathNavigator backup = current.Clone ();\r
- try {\r
- switch (current.NodeType) {\r
- case XPathNodeType.Namespace:\r
- case XPathNodeType.Attribute:\r
- this.MoveToElement ();\r
- goto case XPathNodeType.Element;\r
- case XPathNodeType.Element:\r
- if (MoveToFirstAttribute ())\r
- if (i == 0)\r
- return current.Clone ();\r
- for (int count = 1; this.MoveToNextAttribute (); count++)\r
- if (count == i)\r
- return current.Clone ();\r
- break;\r
+ switch (current.NodeType) {\r
+ case XPathNodeType.Namespace:\r
+ case XPathNodeType.Attribute:\r
+ this.MoveToElement ();\r
+ goto case XPathNodeType.Element;\r
+ case XPathNodeType.Element:\r
+ int count = 0;\r
+ if (MoveToFirstAttribute ()) {\r
+ if (i == 0)\r
+ return true;\r
}\r
- return null;\r
- } finally {\r
- current = backup;\r
+ for (count++; this.MoveToNextAttribute (); count++) {\r
+ if (count == i)\r
+ return true;\r
+ }\r
+ break;\r
}\r
+ return false;\r
}\r
\r
public override string this [int i] {\r
get {\r
- XPathNavigator test = GetAttributeNavigator (i);\r
- if (test != null)\r
- return test.Value;\r
- else\r
- throw new ArgumentOutOfRangeException ();\r
+ XPathNavigator backup = current.Clone ();\r
+ try {\r
+ if (MoveToAttributeNavigator (i))\r
+ return Value;\r
+ else\r
+ throw new ArgumentOutOfRangeException ();\r
+ } finally {\r
+ current.MoveTo (backup);\r
+ }\r
}\r
}\r
\r
}\r
\r
public override bool EOF {\r
- get {\r
- return eof || ReadState == ReadState.EndOfFile;\r
- }\r
+ get { return ReadState == ReadState.EndOfFile; }\r
}\r
\r
public override ReadState ReadState {\r
get {\r
+ if (eof)\r
+ return ReadState.EndOfFile;\r
if (closed)\r
return ReadState.Closed;\r
else if (!started)\r
return ReadState.Initial;\r
- else if (eof)\r
- return ReadState.EndOfFile;\r
return ReadState.Interactive;\r
}\r
}\r
\r
public override void MoveToAttribute (int i)\r
{\r
- XPathNavigator test = GetAttributeNavigator (i);\r
- if (test == null)\r
+ if (!MoveToAttributeNavigator (i))\r
throw new ArgumentOutOfRangeException ();\r
- else {\r
- attributeValueConsumed = false;\r
- current = test;\r
- }\r
}\r
\r
public override bool MoveToFirstAttribute ()\r
\r
public override bool MoveToNextAttribute ()\r
{\r
- if (current.NodeType != XPathNodeType.Attribute) {\r
+ if (current.NodeType == XPathNodeType.Namespace) {\r
bool b = CheckAttributeMove (current.MoveToNextNamespace (XPathNamespaceScope.Local));\r
if (b)\r
return true;\r
+ current.MoveToParent ();\r
+ b = CheckAttributeMove (current.MoveToFirstAttribute ());\r
+ if (b)\r
+ return true;\r
}\r
return CheckAttributeMove (current.MoveToNextAttribute ());\r
}\r