// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION\r
// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.\r
//\r
+\r
using System;\r
using System.Text;\r
using System.Xml;\r
+using System.Xml.Schema;\r
using System.Xml.XPath;\r
\r
namespace Mono.Xml.XPath\r
{\r
public XPathNavigatorReader (XPathNavigator nav)\r
{\r
+ // It seems that this class have only to support linked\r
+ // node as its parameter\r
+ switch (nav.NodeType) {\r
+ case XPathNodeType.Attribute:\r
+ case XPathNodeType.Namespace:\r
+ throw new InvalidOperationException (String.Format ("NodeType {0} is not supported to read as a subtree of an XPathNavigator.", nav.NodeType));\r
+ }\r
root = nav.Clone ();\r
current = nav.Clone ();\r
}\r
bool endElement;\r
bool attributeValueConsumed;\r
StringBuilder readStringBuffer = new StringBuilder ();\r
+#if NET_2_0\r
StringBuilder innerXmlBuilder = new StringBuilder ();\r
+#endif\r
\r
int depth = 0;\r
int attributeCount = 0;\r
bool nextIsEOF;\r
\r
#region Properties\r
+\r
+#if NET_2_0\r
+ public override bool CanReadBinaryContent {\r
+ get { return true; }\r
+ }\r
+\r
+ public override bool CanReadValueChunk {\r
+ get { return true; }\r
+ }\r
+#endif\r
+\r
public override XmlNodeType NodeType \r
{\r
get {\r
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 "http://www.w3.org/2000/xmlns/";\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
get { return current.IsEmptyElement; }\r
}\r
\r
- // It makes no sense.\r
public override bool IsDefault {\r
- get { return false; }\r
+ get {\r
+#if NET_2_0\r
+ IXmlSchemaInfo si = current as IXmlSchemaInfo;\r
+ return si != null && si.IsDefault;\r
+#else\r
+ return false; // no way to check this.\r
+#endif\r
+ }\r
}\r
\r
// It makes no sense.\r
get { return '\"'; }\r
}\r
\r
+#if NET_2_0\r
+ public override IXmlSchemaInfo SchemaInfo {\r
+ get { return current.SchemaInfo; }\r
+ }\r
+#endif\r
+\r
public override string XmlLang {\r
get { return current.XmlLang; }\r
}\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.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
\r
public override bool Read ()\r
{\r
+#if NET_2_0\r
+ if (Binary != null)\r
+ Binary.Reset ();\r
+#endif\r
+\r
switch (ReadState) {\r
case ReadState.EndOfFile:\r
case ReadState.Closed:\r
return false;\r
case ReadState.Initial:\r
started = true;\r
- if (current.NodeType != XPathNodeType.Root)\r
+ switch (current.NodeType) {\r
+ case XPathNodeType.Root:\r
+ // recurse, but as Interactive\r
+ return Read ();\r
+ case XPathNodeType.Element:\r
+ if (current.IsEmptyElement)\r
+ nextIsEOF = true;\r
+ attributeCount = GetAttributeCount ();\r
+ return true;\r
+ default:\r
+ nextIsEOF = true;\r
return true;\r
+ }\r
break;\r
}\r
\r
\r
MoveToElement ();\r
\r
- if (endElement || current.MoveToFirstChild () == false) {\r
- if (current.MoveToNext () == false) {\r
- if (current.IsSamePosition (root)) { // It should happen only when the root node was empty.\r
- eof = true;\r
- return false;\r
- }\r
+ if (endElement || !current.MoveToFirstChild ()) {\r
+ if (current.IsSamePosition (root)) { // It should happen only when the root node was empty.\r
+ eof = true;\r
+ return false;\r
+ }\r
+ if (!current.MoveToNext ()) {\r
current.MoveToParent ();\r
depth--;\r
endElement = (current.NodeType == XPathNodeType.Element);\r
#endregion\r
}\r
}\r
+\r