//
// Author:
// Jason Diamond (jason@injektilo.org)
+// Atsushi Enomoto (atsushi@ximian.com)
//
// (C) 2002 Jason Diamond http://injektilo.org/
+// (C) 2004 Novell Inc.
+//
+
+//
+// Permission is hereby granted, free of charge, to any person obtaining
+// a copy of this software and associated documentation files (the
+// "Software"), to deal in the Software without restriction, including
+// without limitation the rights to use, copy, modify, merge, publish,
+// distribute, sublicense, and/or sell copies of the Software, and to
+// permit persons to whom the Software is furnished to do so, subject to
+// the following conditions:
+//
+// The above copyright notice and this permission notice shall be
+// included in all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
//
using System;
+using System.Collections;
+using System.IO;
+using System.Xml;
+using System.Xml.Schema;
using Mono.Xml.XPath;
+#if NET_2_0
+using MS.Internal.Xml;
+#endif
+
+#if NET_2_0
+using NSResolver = System.Xml.IXmlNamespaceResolver;
+#else
+using NSResolver = System.Xml.XmlNamespaceManager;
+#endif
namespace System.Xml.XPath
{
+#if NET_2_0
+ public abstract class XPathNavigator : XPathItem,
+ ICloneable, IXPathNavigable, IXmlNamespaceResolver
+#else
public abstract class XPathNavigator : ICloneable
+#endif
{
#region Constructor
public abstract string BaseURI { get; }
+#if NET_2_0
+ public virtual bool HasAttributes {
+ get { return Clone ().MoveToFirstAttribute (); }
+ }
+
+ public virtual bool HasChildren {
+ get { return Clone ().MoveToFirstChild (); }
+ }
+#else
public abstract bool HasAttributes { get; }
public abstract bool HasChildren { get; }
+#endif
public abstract bool IsEmptyElement { get; }
public abstract string Prefix { get; }
+#if NET_2_0
+ public virtual string XmlLang {
+ get {
+ XPathNavigator nav = Clone ();
+ switch (nav.NodeType) {
+ case XPathNodeType.Attribute:
+ case XPathNodeType.Namespace:
+ nav.MoveToParent ();
+ break;
+ }
+ do {
+ if (nav.MoveToAttribute ("lang", "http://www.w3.org/XML/1998/namespace"))
+ return nav.Value;
+ } while (nav.MoveToParent ());
+ return String.Empty;
+ }
+ }
+#else
public abstract string Value { get; }
public abstract string XmlLang { get; }
+#endif
int Depth
{
{
while (nDepth1 > nDepth2)
{
- nav1.MoveToParent ();
+ if (!nav1.MoveToParent ())
+ break;
nDepth1 --;
}
if (nav1.IsSamePosition (nav2))
{
while (nDepth1 < nDepth2)
{
- nav2.MoveToParent ();
+ if (!nav2.MoveToParent ())
+ break;
nDepth2 --;
}
if (nav1.IsSamePosition (nav2))
return Evaluate (expr, context, null);
}
- internal virtual object Evaluate (XPathExpression expr, XPathNodeIterator context, XmlNamespaceManager ctx)
+ internal virtual object Evaluate (XPathExpression expr, XPathNodeIterator context, NSResolver ctx)
{
CompiledExpression cexpr = (CompiledExpression) expr;
if (ctx == null)
return cexpr.Evaluate (iterContext);
}
- internal XPathNodeIterator EvaluateNodeSet (XPathExpression expr, XPathNodeIterator context, XmlNamespaceManager ctx)
+ internal XPathNodeIterator EvaluateNodeSet (XPathExpression expr, XPathNodeIterator context, NSResolver ctx)
{
CompiledExpression cexpr = (CompiledExpression) expr;
if (ctx == null)
return cexpr.EvaluateNodeSet (iterContext);
}
- internal string EvaluateString (XPathExpression expr, XPathNodeIterator context, XmlNamespaceManager ctx)
+ internal string EvaluateString (XPathExpression expr, XPathNodeIterator context, NSResolver ctx)
{
CompiledExpression cexpr = (CompiledExpression) expr;
if (ctx == null)
return cexpr.EvaluateString (iterContext);
}
- internal double EvaluateNumber (XPathExpression expr, XPathNodeIterator context, XmlNamespaceManager ctx)
+ internal double EvaluateNumber (XPathExpression expr, XPathNodeIterator context, NSResolver ctx)
{
CompiledExpression cexpr = (CompiledExpression) expr;
if (ctx == null)
return cexpr.EvaluateNumber (iterContext);
}
- internal bool EvaluateBoolean (XPathExpression expr, XPathNodeIterator context, XmlNamespaceManager ctx)
+ internal bool EvaluateBoolean (XPathExpression expr, XPathNodeIterator context, NSResolver ctx)
{
CompiledExpression cexpr = (CompiledExpression) expr;
if (ctx == null)
return cexpr.EvaluateBoolean (iterContext);
}
+#if NET_2_0
+ public virtual string GetAttribute (string localName, string namespaceURI)
+ {
+ XPathNavigator nav = Clone ();
+ if (nav.MoveToAttribute (localName, namespaceURI))
+ return nav.Value;
+ else
+ return String.Empty;
+ }
+
+ public virtual string GetNamespace (string name)
+ {
+ XPathNavigator nav = Clone ();
+ if (nav.MoveToNamespace (name))
+ return nav.Value;
+ else
+ return String.Empty;
+ }
+
+#else
public abstract string GetAttribute (string localName, string namespaceURI);
public abstract string GetNamespace (string name);
+#endif
object ICloneable.Clone ()
{
return Matches (Compile (xpath));
}
- [MonoTODO] // optimize...
public virtual bool Matches (XPathExpression expr)
{
Expression e = ((CompiledExpression) expr).ExpressionNode;
if (e is ExprRoot)
return NodeType == XPathNodeType.Root;
- if (e is NodeTest)
- return ((NodeTest)e).Match (((CompiledExpression)expr).NamespaceManager, this);
+ NodeTest nt = e as NodeTest;
+ if (nt != null) {
+ switch (nt.Axis.Axis) {
+ case Axes.Child:
+ case Axes.Attribute:
+ break;
+ default:
+ throw new XPathException ("Only child and attribute pattern are allowed for a pattern.");
+ }
+ return nt.Match (((CompiledExpression)expr).NamespaceManager, this);
+ }
if (e is ExprFilter) {
do {
e = ((ExprFilter) e).LeftHandSide;
break;
}
- XPathNodeIterator nodes = Select (expr);
-
+ XPathNodeIterator nodes;
+ nodes = this.Select (expr);
while (nodes.MoveNext ()) {
if (IsSamePosition (nodes.Current))
return true;
}
// ancestors might select this node.
- if (!e.NeedAbsoluteMatching)
- return false;
XPathNavigator navigator = Clone ();
public abstract bool MoveTo (XPathNavigator other);
+#if NET_2_0
+ public virtual bool MoveToAttribute (string localName, string namespaceURI)
+ {
+ if (MoveToFirstAttribute ()) {
+ do {
+ if (LocalName == localName && NamespaceURI == namespaceURI)
+ return true;
+ } while (MoveToNextAttribute ());
+ MoveToParent ();
+ }
+ return false;
+ }
+
+ public virtual bool MoveToNamespace (string name)
+ {
+ if (MoveToFirstNamespace ()) {
+ do {
+ if (LocalName == name)
+ return true;
+ } while (MoveToNextNamespace ());
+ MoveToParent ();
+ }
+ return false;
+ }
+
+ public virtual bool MoveToFirst ()
+ {
+ if (MoveToPrevious ()) {
+ // It would be able to invoke MoveToPrevious() until the end, but this way would be much faster
+ MoveToParent ();
+ MoveToFirstChild ();
+ return true;
+ }
+ return false;
+ }
+
+ public virtual void MoveToRoot ()
+ {
+ while (MoveToParent ())
+ ;
+ }
+#else
public abstract bool MoveToAttribute (string localName, string namespaceURI);
+ public abstract bool MoveToNamespace (string name);
+
public abstract bool MoveToFirst ();
+ public abstract void MoveToRoot ();
+#endif
+
public abstract bool MoveToFirstAttribute ();
public abstract bool MoveToFirstChild ();
public abstract bool MoveToId (string id);
- public abstract bool MoveToNamespace (string name);
-
public abstract bool MoveToNext ();
public abstract bool MoveToNextAttribute ();
public abstract bool MoveToPrevious ();
- public abstract void MoveToRoot ();
-
public virtual XPathNodeIterator Select (string xpath)
{
return Select (Compile (xpath));
return Select (expr, null);
}
- internal virtual XPathNodeIterator Select (XPathExpression expr, XmlNamespaceManager ctx)
+ internal virtual XPathNodeIterator Select (XPathExpression expr, NSResolver ctx)
{
CompiledExpression cexpr = (CompiledExpression) expr;
if (ctx == null)
ctx = cexpr.NamespaceManager;
BaseIterator iter = new NullIterator (this, ctx);
- return cexpr.EvaluateNodeSet (iter);
+ return cexpr.EvaluateNodeSet (iter);
}
public virtual XPathNodeIterator SelectAncestors (XPathNodeType type, bool matchSelf)
}
#endregion
+
+#if NET_2_0
+
+ [MonoTODO]
+ public virtual bool CheckValidity (XmlSchemaSet schemas, ValidationEventHandler handler)
+ {
+ throw new NotImplementedException ();
+ }
+
+ [MonoTODO]
+ public virtual object CopyAsObject (Type targetType)
+ {
+ throw new NotImplementedException ();
+ }
+
+ public virtual XPathNavigator CreateNavigator ()
+ {
+ return Clone ();
+ }
+
+ [MonoTODO]
+ public virtual object Evaluate (string xpath, IXmlNamespaceResolver nsResolver)
+ {
+ return Evaluate (Compile (xpath), null, nsResolver);
+ }
+
+ [MonoTODO]
+ public virtual IDictionary GetNamespacesInScope (XmlNamespaceScope scope)
+ {
+ throw new NotImplementedException ();
+ }
+
+ public virtual string LookupNamespace (string prefix)
+ {
+ return LookupNamespace (prefix, false);
+ }
+
+ public virtual string LookupNamespace (string prefix, bool atomizedNames)
+ {
+ XPathNavigator nav = Clone ();
+ if (nav.NodeType != XPathNodeType.Element)
+ nav.MoveToParent ();
+ if (nav.MoveToNamespace (prefix)) {
+ if (atomizedNames)
+ return nav.NameTable.Add (nav.Value);
+ else
+ return nav.Value;
+ }
+ return null;
+ }
+
+ public virtual string LookupPrefix (string namespaceUri)
+ {
+ return LookupPrefix (namespaceUri, false);
+ }
+
+ [MonoTODO]
+ public virtual string LookupPrefix (string namespaceUri, bool atomizedNames)
+ {
+ throw new NotImplementedException ();
+ }
+
+ public virtual bool MoveToAttribute (string localName, string namespaceURI, bool atomizedNames)
+ {
+ return MoveToAttribute (localName, namespaceURI);
+ }
+
+ private bool MoveTo (XPathNodeIterator iter)
+ {
+ if (iter.MoveNext ()) {
+ MoveTo (iter.Current);
+ return true;
+ }
+ else
+ return false;
+ }
+
+ public virtual bool MoveToChild (XPathNodeType type)
+ {
+ return MoveTo (SelectChildren (type));
+ }
+
+ public virtual bool MoveToChild (string localName, string namespaceURI)
+ {
+ return MoveTo (SelectChildren (localName, namespaceURI));
+ }
+
+ public virtual bool MoveToChild (string localName, string namespaceURI, bool atomizedNames)
+ {
+ return MoveToChild (localName, namespaceURI);
+ }
+
+ public virtual bool MoveToDescendant (XPathNodeType type)
+ {
+ return MoveTo (SelectDescendants (type, false));
+ }
+
+ public virtual bool MoveToDescendant (string localName, string namespaceURI)
+ {
+ return MoveTo (SelectDescendants (localName, namespaceURI, false));
+ }
+
+ public virtual bool MoveToDescendant (string localName, string namespaceURI, bool atomizedNames)
+ {
+ return MoveToDescendant (localName, namespaceURI);
+ }
+
+ public virtual bool MoveToNext (string localName, string namespaceURI)
+ {
+ XPathNavigator nav = Clone ();
+ while (nav.MoveToNext ()) {
+ if (nav.LocalName == localName &&
+ nav.NamespaceURI == namespaceURI) {
+ MoveTo (nav);
+ return true;
+ }
+ }
+ return false;
+ }
+
+ public virtual bool MoveToNext (string localName, string namespaceURI, bool atomizedNames)
+ {
+ return MoveToNext (localName, namespaceURI);
+ }
+
+ public virtual bool MoveToNext (XPathNodeType type)
+ {
+ XPathNavigator nav = Clone ();
+ while (nav.MoveToNext ()) {
+ if (nav.NodeType == type) {
+ MoveTo (nav);
+ return true;
+ }
+ }
+ return false;
+ }
+
+ [MonoTODO]
+ public virtual XmlReader ReadSubtree ()
+ {
+ throw new NotImplementedException ();
+ }
+
+ public virtual XPathNodeIterator Select (string xpath, IXmlNamespaceResolver nsResolver)
+ {
+ return Select (Compile (xpath), nsResolver);
+ }
+
+ public virtual XPathNavigator SelectSingleNode (string xpath)
+ {
+ return SelectSingleNode (xpath, null);
+ }
+
+ public virtual XPathNavigator SelectSingleNode (string xpath, IXmlNamespaceResolver nsResolver)
+ {
+ XPathExpression expr = Compile (xpath);
+ expr.SetContext (nsResolver);
+ return SelectSingleNode (expr);
+ }
+
+ public XPathNavigator SelectSingleNode (XPathExpression expression)
+ {
+ XPathNodeIterator iter = Select (expression);
+ if (iter.MoveNext ())
+ return iter.Current;
+ else
+ return null;
+ }
+
+ [MonoTODO]
+ public override object ValueAs (Type type, IXmlNamespaceResolver nsResolver)
+ {
+ throw new NotImplementedException ();
+ }
+
+ [MonoTODO]
+ public virtual void WriteSubtree (XmlWriter writer)
+ {
+ XmlReader st = ReadSubtree ();
+ writer.WriteNode (st, false);
+ }
+
+ [MonoTODO]
+ public virtual string InnerXml {
+ get { throw new NotImplementedException (); }
+ }
+
+ [MonoTODO]
+ public override bool IsNode {
+ get { return true; }
+ }
+
+ [MonoTODO]
+ public virtual IKeyComparer NavigatorComparer {
+ get { throw new NotImplementedException (); }
+ }
+
+ [MonoTODO]
+ public virtual string OuterXml {
+ get {
+ StringWriter sw = new StringWriter ();
+ XmlTextWriter xtw = new XmlTextWriter (sw);
+ WriteSubtree (xtw);
+ xtw.Close ();
+ return sw.ToString ();
+ }
+ }
+
+ [MonoTODO]
+ public virtual IXmlSchemaInfo SchemaInfo {
+ get { throw new NotImplementedException (); }
+ }
+
+ [MonoTODO]
+ public override object TypedValue {
+ get { throw new NotImplementedException (); }
+ }
+
+ [MonoTODO]
+ public virtual object UnderlyingObject {
+ get { throw new NotImplementedException (); }
+ }
+
+ [MonoTODO]
+ public override bool ValueAsBoolean {
+ get { return XQueryConvert.StringToBoolean (Value); }
+ }
+
+ [MonoTODO]
+ public override DateTime ValueAsDateTime {
+ get { return XmlConvert.ToDateTime (Value); }
+ }
+
+ [MonoTODO]
+ public override decimal ValueAsDecimal {
+ get { return XQueryConvert.StringToDecimal (Value); }
+ }
+
+ [MonoTODO]
+ public override double ValueAsDouble {
+ get { return XQueryConvert.StringToDouble (Value); }
+ }
+
+ [MonoTODO]
+ public override int ValueAsInt32 {
+ get { return XQueryConvert.StringToInt (Value); }
+ }
+
+ [MonoTODO]
+ public override long ValueAsInt64 {
+ get { return XQueryConvert.StringToInteger (Value); }
+ }
+
+ [MonoTODO]
+ public override ICollection ValueAsList {
+ get { throw new NotImplementedException (); }
+ }
+
+ [MonoTODO]
+ public override float ValueAsSingle {
+ get { return XQueryConvert.StringToFloat (Value); }
+ }
+
+ [MonoTODO]
+ public override Type ValueType {
+ get { throw new NotImplementedException (); }
+ }
+
+ [MonoTODO]
+ public override XmlSchemaType XmlType {
+ get { throw new NotImplementedException (); }
+ }
+
+ [MonoTODO]
+ protected XmlReader GetValidatingReader (XmlSchemaSet schemas, ValidationEventHandler handler, XmlSchemaType schemaType)
+ {
+ throw new NotImplementedException ();
+ }
+#endif
}
}