public virtual void WriteNode(XPathNavigator navigator, bool defattr) {
if (navigator == null) {
throw new ArgumentNullException("navigator");
}
int iLevel = 0;
navigator = navigator.Clone();
while (true) {
bool mayHaveChildren = false;
XPathNodeType nodeType = navigator.NodeType;
switch (nodeType) {
case XPathNodeType.Element:
WriteStartElement(navigator.Prefix, navigator.LocalName, navigator.NamespaceURI);
// Copy attributes
if (navigator.MoveToFirstAttribute()) {
do {
IXmlSchemaInfo schemaInfo = navigator.SchemaInfo;
if (defattr || (schemaInfo == null || !schemaInfo.IsDefault)) {
WriteStartAttribute(navigator.Prefix, navigator.LocalName, navigator.NamespaceURI);
// copy string value to writer
WriteString(navigator.Value);
WriteEndAttribute();
}
} while (navigator.MoveToNextAttribute());
navigator.MoveToParent();
}
// Copy namespaces
if (navigator.MoveToFirstNamespace(XPathNamespaceScope.Local)) {
WriteLocalNamespaces(navigator);
navigator.MoveToParent();
}
mayHaveChildren = true;
break;
case XPathNodeType.Attribute:
// do nothing on root level attribute
break;
case XPathNodeType.Text:
WriteString(navigator.Value);
break;
case XPathNodeType.SignificantWhitespace:
case XPathNodeType.Whitespace:
WriteWhitespace(navigator.Value);
break;
case XPathNodeType.Root:
mayHaveChildren = true;
break;
case XPathNodeType.Comment:
WriteComment(navigator.Value);
break;
case XPathNodeType.ProcessingInstruction:
WriteProcessingInstruction(navigator.LocalName, navigator.Value);
break;
case XPathNodeType.Namespace:
// do nothing on root level namespace
break;
default:
Debug.Assert(false);
break;
}
if (mayHaveChildren) {
// If children exist, move down to next level
if (navigator.MoveToFirstChild()) {
iLevel++;
continue;
}
else {
// EndElement
if (navigator.NodeType == XPathNodeType.Element) {
if (navigator.IsEmptyElement) {
WriteEndElement();
}
else {
WriteFullEndElement();
}
}
}
}
// No children
while (true) {
if (iLevel == 0) {
// The entire subtree has been copied
return;
}
if (navigator.MoveToNext()) {
// Found a sibling, so break to outer loop
break;
}
// No siblings, so move up to previous level
iLevel--;
navigator.MoveToParent();
// EndElement
if (navigator.NodeType == XPathNodeType.Element)
WriteFullEndElement();
}
}
}