public XPathNavigatorReader (XPathNavigator nav)\r
{\r
root = nav.Clone ();\r
- root.MoveToRoot ();\r
current = nav.Clone ();\r
}\r
\r
StringBuilder readStringBuffer = new StringBuilder ();\r
StringBuilder innerXmlBuilder = new StringBuilder ();\r
\r
+ int depth = 0;\r
+ int attributeCount = 0;\r
+ bool eof;\r
+ bool nextIsEOF;\r
+\r
#region Properties\r
public override XmlNodeType NodeType \r
{\r
}\r
\r
public override string Name {\r
- get { return current.Name; }\r
+ get { return eof ? String.Empty : current.Name; }\r
}\r
\r
public override string LocalName {\r
- get { return current.LocalName; }\r
+ get { return eof ? String.Empty : current.LocalName; }\r
}\r
\r
public override string NamespaceURI {\r
- get { return current.NamespaceURI; }\r
+ get { return eof ? String.Empty : current.NamespaceURI; }\r
}\r
\r
public override string Prefix {\r
- get { return current.Prefix; }\r
+ get { return eof ? String.Empty : current.Prefix; }\r
}\r
\r
public override bool HasValue {\r
\r
public override int Depth {\r
get {\r
- if (current.IsSamePosition (root))\r
+ switch (ReadState) {\r
+ case ReadState.EndOfFile:\r
+ case ReadState.Initial:\r
+ case ReadState.Closed:\r
return 0;\r
- XPathNavigator tmp = current.Clone ();\r
- // top level nodes' depth = 0.\r
- int depth = -1;\r
- while (!tmp.IsSamePosition (root)) {\r
- tmp.MoveToParent ();\r
- depth ++;\r
}\r
return depth;\r
}\r
}\r
\r
public override int AttributeCount {\r
- get {\r
- XPathNavigator backup = null;\r
- try {\r
- switch (current.NodeType) {\r
- case XPathNodeType.Namespace:\r
- case XPathNodeType.Attribute:\r
- backup = current.Clone ();\r
- current.MoveToParent ();\r
- goto case XPathNodeType.Element;\r
- case XPathNodeType.Element:\r
- int count = 0;\r
- if (current.MoveToFirstAttribute ())\r
- do {\r
- count++;\r
- } while (current.MoveToNextAttribute ());\r
- current.MoveToParent ();\r
- if (current.MoveToFirstNamespace (XPathNamespaceScope.Local))\r
- do {\r
- count++;\r
- } while (current.MoveToNextNamespace (XPathNamespaceScope.Local));\r
- current.MoveToParent ();\r
- return count;\r
- }\r
- // default\r
- return 0;\r
- } finally {\r
- if (backup != null)\r
- current = backup;\r
- }\r
+ get { return attributeCount; }\r
+ }\r
+\r
+ private int GetAttributeCount ()\r
+ {\r
+ int count = 0;\r
+ if (current.MoveToFirstAttribute ()) {\r
+ do {\r
+ count++;\r
+ } while (current.MoveToNextAttribute ());\r
+ current.MoveToParent ();\r
+ }\r
+ if (current.MoveToFirstNamespace (XPathNamespaceScope.Local)) {\r
+ do {\r
+ count++;\r
+ } while (current.MoveToNextNamespace (XPathNamespaceScope.Local));\r
+ current.MoveToParent ();\r
}\r
+ return count;\r
}\r
\r
private XPathNavigator GetAttributeNavigator (int i)\r
\r
public override bool EOF {\r
get {\r
- return ReadState == ReadState.EndOfFile;\r
+ return eof || ReadState == ReadState.EndOfFile;\r
}\r
}\r
\r
get {\r
if (closed)\r
return ReadState.Closed;\r
- if (!started)\r
+ else if (!started)\r
return ReadState.Initial;\r
- else if (current.IsSamePosition (root))\r
+ else if (eof)\r
return ReadState.EndOfFile;\r
return ReadState.Interactive;\r
}\r
\r
public override void Close ()\r
{\r
- // It is kinda hack to make ReadState EOF.\r
- current = root;\r
closed = true;\r
+ eof = true;\r
}\r
\r
public override bool Read ()\r
case ReadState.Closed:\r
case ReadState.Error:\r
return false;\r
+ case ReadState.Initial:\r
+ started = true;\r
+ if (current.NodeType != XPathNodeType.Root)\r
+ return true;\r
+ break;\r
+ }\r
+\r
+ if (nextIsEOF) {\r
+ nextIsEOF = false;\r
+ eof = true;\r
+ return false;\r
}\r
- started = true;\r
- this.MoveToElement ();\r
+\r
+ MoveToElement ();\r
\r
if (endElement || current.MoveToFirstChild () == false) {\r
if (current.MoveToNext () == false) {\r
- current.MoveToParent ();\r
- if (ReadState == ReadState.EndOfFile)\r
+ if (current.IsSamePosition (root)) { // It should happen only when the root node was empty.\r
+ eof = true;\r
return false;\r
- endElement = true;\r
+ }\r
+ current.MoveToParent ();\r
+ depth--;\r
+ if (current.IsSamePosition (root)) {\r
+ if (current.NodeType == XPathNodeType.Element)\r
+ nextIsEOF = true;\r
+ else {\r
+ eof = true;\r
+ return false;\r
+ }\r
+ }\r
+ if (current.NodeType == XPathNodeType.Element)\r
+ endElement = true;\r
} else\r
endElement = false;\r
}\r
+ else if (!endElement)\r
+ depth++;\r
+ attributeCount = GetAttributeCount ();\r
return true;\r
}\r
\r