XmlNode parent;
XmlNode current;
XmlNode nextSibling;
- Stack nodeStack = new Stack ();
+ WriteState state;
+ XmlAttribute attribute;
public XmlDocumentInsertionWriter (XmlNode owner, XmlNode nextSibling)
{
state = WriteState.Content;
}
- WriteState state;
- XmlAttribute attribute;
-
public override WriteState WriteState {
get { return state; }
}
public override void Close ()
{
- while (nodeStack.Count > 0) {
- XmlNode n = nodeStack.Pop () as XmlNode;
- n.AppendChild (current);
- current = n;
- }
+ while (current.ParentNode != null)
+ current = current.ParentNode;
+
parent.InsertBefore ((XmlDocumentFragment) current, nextSibling);
if (Closed != null)
Closed (this);
internal event XmlWriterClosedEventHandler Closed;
- internal XmlNode AppendedFirstChild;
-
public override void Flush ()
{
}
{
if (state != WriteState.Content)
throw new InvalidOperationException ("Current state is not inside element. Cannot start attribute.");
+ if (prefix == null && ns != null && ns.Length > 0)
+ prefix = LookupPrefix (ns);
attribute = current.OwnerDocument.CreateAttribute (prefix, name, ns);
state = WriteState.Attribute;
}
public override void WriteStartElement (string prefix, string name, string ns)
{
+ if (prefix == null && ns != null && ns.Length > 0)
+ prefix = LookupPrefix (ns);
XmlElement el = current.OwnerDocument.CreateElement (prefix, name, ns);
current.AppendChild (el);
- nodeStack.Push (current);
current = el;
}
public override void WriteEndElement ()
{
- if (nodeStack.Count == 0)
+ current = current.ParentNode;
+ if (current == null)
throw new InvalidOperationException ("No element is opened.");
- current = nodeStack.Pop () as XmlNode;
}
public override void WriteFullEndElement ()
public override void WriteRaw (string raw)
{
- throw new NotSupportedException ();
+ XmlReader reader = new XmlTextReader(new System.IO.StringReader(raw));
+ WriteRaw(reader);
+ }
+
+ private void WriteRaw(XmlReader reader)
+ {
+ if (reader != null && reader.NodeType == XmlNodeType.Element)
+ {
+ WriteStartElement (reader.Prefix, reader.LocalName, reader.NamespaceURI);
+ WriteAttributes (reader, true);
+ WriteRaw (reader.ReadSubtree ());
+ WriteEndElement ();
+
+ }
}
public override void WriteSurrogateCharEntity (char msb, char lsb)
public override void WriteEndAttribute ()
{
- XmlElement element = current as XmlElement;
+ // when the writer is for AppendChild() and the root
+ // node is element, it allows to write attributes
+ // (IMHO incorrectly: isn't it append "child" ???)
+ XmlElement element = (current as XmlElement) ?? (nextSibling == null ? parent as XmlElement : null);
if (state != WriteState.Attribute || element == null)
throw new InvalidOperationException ("Current state is not inside attribute. Cannot close attribute.");
element.SetAttributeNode (attribute);
internal class XmlDocumentAttributeWriter : XmlWriter
{
XmlElement element;
+ WriteState state;
+ XmlAttribute attribute;
public XmlDocumentAttributeWriter (XmlNode owner)
{
state = WriteState.Content;
}
- WriteState state;
- XmlAttribute attribute;
-
public override WriteState WriteState {
get { return state; }
}
{
if (state != WriteState.Content)
throw new InvalidOperationException ("Current state is not inside element. Cannot start attribute.");
+ if (prefix == null && ns != null && ns.Length > 0)
+ prefix = LookupPrefix (ns);
attribute = element.OwnerDocument.CreateAttribute (prefix, name, ns);
state = WriteState.Attribute;
}
get { return navigator.BaseURI; }
}
+ public override bool CanEdit {
+ get { return true; }
+ }
+
public override bool IsEmptyElement {
get { return navigator.IsEmptyElement; }
}
get { return navigator.Value; }
}
+ public override string XmlLang {
+ get { return navigator.XmlLang; }
+ }
+
+ public override bool HasChildren {
+ get { return navigator.HasChildren; }
+ }
+
+ public override bool HasAttributes {
+ get { return navigator.HasAttributes; }
+ }
+
public override XPathNavigator Clone ()
{
return new XmlDocumentEditableNavigator (this);
public override XPathNavigator CreateNavigator ()
{
- return navigator.Clone ();
+ return Clone ();
}
public XmlNode GetNode ()
public override void DeleteSelf ()
{
XmlNode n = ((IHasXmlNode) navigator).GetNode ();
- if (!navigator.MoveToNext ())
+ XmlAttribute a = n as XmlAttribute;
+ if (a != null) {
+ if (a.OwnerElement == null)
+ throw new InvalidOperationException ("This attribute node cannot be removed since it has no owner element.");
navigator.MoveToParent ();
- if (n.ParentNode == null)
- throw new InvalidOperationException ("This node cannot be removed since it has no parent.");
- n.ParentNode.RemoveChild (n);
+ a.OwnerElement.RemoveAttributeNode (a);
+ } else {
+ if (n.ParentNode == null)
+ throw new InvalidOperationException ("This node cannot be removed since it has no parent.");
+ navigator.MoveToParent ();
+ n.ParentNode.RemoveChild (n);
+ }
}
public override void ReplaceSelf (XmlReader reader)
n.RemoveChild (n.FirstChild);
n.InnerText = value;
}
+
+ public override void MoveToRoot ()
+ {
+ navigator.MoveToRoot ();
+ }
+
+ public override bool MoveToNamespace (string name)
+ {
+ return navigator.MoveToNamespace (name);
+ }
+
+ public override bool MoveToFirst ()
+ {
+ return navigator.MoveToFirst ();
+ }
+
+ public override bool MoveToAttribute (string localName, string namespaceURI)
+ {
+ return navigator.MoveToAttribute (localName, namespaceURI);
+ }
+
+ public override bool IsDescendant (XPathNavigator nav)
+ {
+ XmlDocumentEditableNavigator e = nav as XmlDocumentEditableNavigator;
+ if (e != null)
+ return navigator.IsDescendant (e.navigator);
+ else
+ return navigator.IsDescendant (nav);
+ }
+
+ public override string GetNamespace (string name)
+ {
+ return navigator.GetNamespace (name);
+ }
+
+ public override string GetAttribute (string localName, string namespaceURI)
+ {
+ return navigator.GetAttribute (localName, namespaceURI);
+ }
+
+ public override XmlNodeOrder ComparePosition (XPathNavigator nav)
+ {
+ XmlDocumentEditableNavigator e = nav as XmlDocumentEditableNavigator;
+ if (e != null)
+ return navigator.ComparePosition (e.navigator);
+ else
+ return navigator.ComparePosition (nav);
+ }
}
}