DefaultContext.cs :  » 2.6.4-mono-.net-core » System.Xml » System » Xml » XPath » C# / CSharp Open Source

Home
C# / CSharp Open Source
1.2.6.4 mono .net core
2.2.6.4 mono core
3.Aspect Oriented Frameworks
4.Bloggers
5.Build Systems
6.Business Application
7.Charting Reporting Tools
8.Chat Servers
9.Code Coverage Tools
10.Content Management Systems CMS
11.CRM ERP
12.Database
13.Development
14.Email
15.Forum
16.Game
17.GIS
18.GUI
19.IDEs
20.Installers Generators
21.Inversion of Control Dependency Injection
22.Issue Tracking
23.Logging Tools
24.Message
25.Mobile
26.Network Clients
27.Network Servers
28.Office
29.PDF
30.Persistence Frameworks
31.Portals
32.Profilers
33.Project Management
34.RSS RDF
35.Rule Engines
36.Script
37.Search Engines
38.Sound Audio
39.Source Control
40.SQL Clients
41.Template Engines
42.Testing
43.UML
44.Web Frameworks
45.Web Service
46.Web Testing
47.Wiki Engines
48.Windows Presentation Foundation
49.Workflows
50.XML Parsers
C# / C Sharp
C# / C Sharp by API
C# / CSharp Tutorial
C# / CSharp Open Source » 2.6.4 mono .net core » System.Xml 
System.Xml » System » Xml » XPath » DefaultContext.cs
//
// System.Xml.XPath.DefaultContext & support classes
//
// Author:
//   Piers Haken (piersh@friskit.com)
//
// (C) 2002 Piers Haken
//

//
// 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.Globalization;
using System.Xml;
using System.Xml.XPath;
using System.Xml.Xsl;
using System.Text;

namespace System.Xml.XPath{
  internal class XPathFunctions
  {
    public static bool ToBoolean (object arg)
    {
      if (arg == null)
        throw new ArgumentNullException ();
      if (arg is bool)
        return (bool) arg;
      if (arg is double)
      {
        double dArg = (double) arg;
        return (dArg != 0.0 && !double.IsNaN (dArg));
      }
      if (arg is string)
        return ((string) arg).Length != 0;
      if (arg is XPathNodeIterator)
      {
        XPathNodeIterator iter = (XPathNodeIterator) arg;
        return iter.MoveNext ();
      }
      if (arg is XPathNavigator)
      {
        return ToBoolean (((XPathNavigator) arg).SelectChildren (XPathNodeType.All));
      }
      throw new ArgumentException ();
    }

    public static bool ToBoolean (bool b)
    {
      return b;
    }

    public static bool ToBoolean (double d)
    {
      return d != 0.0 && !Double.IsNaN (d);
    }

    public static bool ToBoolean (string s)
    {
      return s != null && s.Length > 0;
    }

    public static bool ToBoolean (BaseIterator iter)
    {
      return iter != null && iter.MoveNext ();
    }

    public static string ToString (object arg)
    {
      if (arg == null)
        throw new ArgumentNullException ();
      if (arg is string)
        return (string) arg;
      if (arg is bool)
        return ((bool) arg) ? "true" : "false";
      if (arg is double)
        return ToString ((double) arg);
      if (arg is XPathNodeIterator)
      {
        XPathNodeIterator iter = (XPathNodeIterator) arg;
        if (!iter.MoveNext ())
          return "";
        return iter.Current.Value;
      }
      if (arg is XPathNavigator)
      {
        return ((XPathNavigator) arg).Value;
      }
      throw new ArgumentException ();
    }

    public static string ToString (double d)
    {
      // See XPath 1.0 section 4.2
      if (d == Double.NegativeInfinity)
        return "-Infinity";
      if (d == Double.PositiveInfinity)
        return "Infinity";
      return d.ToString ("R", NumberFormatInfo.InvariantInfo);
    }

    public static double ToNumber (object arg)
    {
      if (arg == null)
        throw new ArgumentNullException ();
      if (arg is BaseIterator || arg is XPathNavigator)
        arg = ToString (arg);  // follow on
      if (arg is string) {
        string s = arg as string;
        return ToNumber (s); // use explicit overload
      }
      if (arg is double)
        return (double) arg;
      if (arg is bool)
        return Convert.ToDouble ((bool) arg);
      throw new ArgumentException ();
    }
    
    public static double ToNumber (string arg)
    {
      if (arg == null)
        throw new ArgumentNullException ();
      string s = arg.Trim (XmlChar.WhitespaceChars);
      if (s.Length == 0)
        return double.NaN;
      try {
        // workaround for allowed ".xxx" style.
        if (s [0] == '.')
          s = '.' + s;
        return Double.Parse (s, NumberStyles.AllowLeadingWhite | NumberStyles.AllowTrailingWhite | NumberStyles.AllowLeadingSign | NumberStyles.AllowDecimalPoint, NumberFormatInfo.InvariantInfo);
      } catch (System.OverflowException) {
        return double.NaN;
      } catch (System.FormatException) {
        return double.NaN;
      }
    }
  }

  internal abstract class XPathFunction : Expression
  {
    public XPathFunction (FunctionArguments args) {}
  }


  internal class XPathFunctionLast : XPathFunction
  {
    public XPathFunctionLast (FunctionArguments args) : base (args)
    {
      if (args != null)
        throw new XPathException ("last takes 0 args");
    }
    
    public override XPathResultType ReturnType { get { return XPathResultType.Number; }}

    internal override bool Peer {
      get { return true; }
    }

    public override object Evaluate (BaseIterator iter)
    {
      return (double) iter.Count;
    }

    public override string ToString ()
    {
      return "last()";
    }

    internal override bool IsPositional {
      get { return true; }
    }
  }


  internal class XPathFunctionPosition : XPathFunction
  {
    public XPathFunctionPosition (FunctionArguments args) : base (args)
    {
      if (args != null)
        throw new XPathException ("position takes 0 args");
    }
    
    public override XPathResultType ReturnType { get { return XPathResultType.Number; }}

    internal override bool Peer {
      get { return true; }
    }

    public override object Evaluate (BaseIterator iter)
    {
      return (double) iter.CurrentPosition;
    }

    public override string ToString ()
    {
      return "position()";
    }

    internal override bool IsPositional {
      get { return true; }
    }
  }


  internal class XPathFunctionCount : XPathFunction
  {
    Expression arg0;
    
    public XPathFunctionCount (FunctionArguments args) : base (args)
    {
      if (args == null || args.Tail != null)
        throw new XPathException ("count takes 1 arg");
      
      arg0 = args.Arg;
    }

    public override XPathResultType ReturnType { get { return XPathResultType.Number; }}

    internal override bool Peer {
      get { return arg0.Peer; }
    }

    public override object Evaluate (BaseIterator iter)
    {
      return (double) arg0.EvaluateNodeSet (iter).Count;
    }
    
    public override bool EvaluateBoolean (BaseIterator iter)
    {
      if (arg0.GetReturnType (iter) == XPathResultType.NodeSet)
        return arg0.EvaluateBoolean (iter);
      
      return arg0.EvaluateNodeSet (iter).MoveNext ();
    }

    public override string ToString ()
    {
      return "count(" + arg0.ToString () + ")";
    }
  }


  internal class XPathFunctionId : XPathFunction
  {
    Expression arg0;
    
    public XPathFunctionId (FunctionArguments args) : base (args)
    {
      if (args == null || args.Tail != null)
        throw new XPathException ("id takes 1 arg");
      
      arg0 = args.Arg;
    }

    public Expression Id { get { return arg0; } }
    
    private static char [] rgchWhitespace = {' ', '\t', '\r', '\n'};
    public override XPathResultType ReturnType { get { return XPathResultType.NodeSet; }}

    internal override bool Peer {
      get { return arg0.Peer; }
    }

    public override object Evaluate (BaseIterator iter)
    {
      String strArgs;
      object val = arg0.Evaluate (iter);
      
      XPathNodeIterator valItr = val as XPathNodeIterator;
      if (valItr != null)
      {
        strArgs = "";
        while (valItr.MoveNext ())
          strArgs += valItr.Current.Value + " ";
      }
      else
        strArgs = XPathFunctions.ToString (val);
      
      XPathNavigator n = iter.Current.Clone ();
      ArrayList rgNodes = new ArrayList ();
      string [] ids = strArgs.Split (rgchWhitespace);
      for (int i = 0; i < ids.Length; i++)
        if (n.MoveToId (ids [i]))
          rgNodes.Add (n.Clone ());

      rgNodes.Sort (XPathNavigatorComparer.Instance);
      return new ListIterator (iter, rgNodes);
    }

    public override string ToString ()
    {
      return "id(" + arg0.ToString () + ")";
    }
  }

  internal class XPathFunctionLocalName : XPathFunction
  {
    Expression arg0;
    
    public XPathFunctionLocalName (FunctionArguments args) : base (args)
    {
      if (args != null) {
        arg0 = args.Arg;
        if (args.Tail != null)
          throw new XPathException ("local-name takes 1 or zero args");
      }
    }
    
    public override XPathResultType ReturnType { get { return XPathResultType.String; }}

    internal override bool Peer {
      get { return arg0 != null ? arg0.Peer : true; }
    }
    
    public override object Evaluate (BaseIterator iter)
    {
      if (arg0 == null)
        return iter.Current.LocalName;
      
      BaseIterator argNs = arg0.EvaluateNodeSet (iter);
      if (argNs == null || !argNs.MoveNext ())
        return "";
      return argNs.Current.LocalName;
    }

    public override string ToString ()
    {
      return "local-name(" + arg0.ToString () + ")";
    }
  }


  internal class XPathFunctionNamespaceUri : XPathFunction
  {
    Expression arg0;
    
    public XPathFunctionNamespaceUri (FunctionArguments args) : base (args)
    {
      if (args != null) {
        arg0 = args.Arg;
        if (args.Tail != null)
          throw new XPathException ("namespace-uri takes 1 or zero args");
      }
    }

    internal override bool Peer {
      get { return arg0 != null ? arg0.Peer : true; }
    }
    
    public override XPathResultType ReturnType { get { return XPathResultType.String; }}
    
    public override object Evaluate (BaseIterator iter)
    {
      if (arg0 == null)
        return iter.Current.NamespaceURI;
      
      BaseIterator argNs = arg0.EvaluateNodeSet (iter);
      if (argNs == null || !argNs.MoveNext ())
        return "";
      return argNs.Current.NamespaceURI;
    }

    public override string ToString ()
    {
      return "namespace-uri(" + arg0.ToString () + ")";
    }
  }


  internal class XPathFunctionName : XPathFunction
  {
    Expression arg0;
    
    public XPathFunctionName (FunctionArguments args) : base (args)
    {
      if (args != null) {
        arg0 = args.Arg;
        if (args.Tail != null)
          throw new XPathException ("name takes 1 or zero args");
      }
    }
    
    public override XPathResultType ReturnType { get { return XPathResultType.String; }}

    internal override bool Peer {
      get { return arg0 != null ? arg0.Peer : true; }
    }
    
    public override object Evaluate (BaseIterator iter)
    {
      if (arg0 == null)
        return iter.Current.Name;
      
      BaseIterator argNs = arg0.EvaluateNodeSet (iter);
      if (argNs == null || !argNs.MoveNext ())
        return "";
      return argNs.Current.Name;
    }

    public override string ToString ()
    {
      return String.Concat ("name(",
         arg0 != null ? arg0.ToString () : String.Empty,
         ")");
    }
  }


  internal class XPathFunctionString : XPathFunction
  {
    Expression arg0;
    
    public XPathFunctionString (FunctionArguments args) : base (args)
    {
      if (args != null) {
        arg0 = args.Arg;
        if (args.Tail != null)
          throw new XPathException ("string takes 1 or zero args");
      }
    }
    
    public override XPathResultType ReturnType { get { return XPathResultType.String; }}

    internal override bool Peer {
      get { return arg0 != null ? arg0.Peer : true; }
    }

    public override object Evaluate (BaseIterator iter)
    {
      if (arg0 == null)
        return iter.Current.Value;
      return arg0.EvaluateString (iter);
    }

    public override string ToString ()
    {
      return "string(" + arg0.ToString () + ")";
    }
  }


  internal class XPathFunctionConcat : XPathFunction
  {
    ArrayList rgs;
    
    public XPathFunctionConcat (FunctionArguments args) : base (args)
    {
      if (args == null || args.Tail == null)
        throw new XPathException ("concat takes 2 or more args");
      
      args.ToArrayList (rgs = new ArrayList ());
    }
    
    public override XPathResultType ReturnType { get { return XPathResultType.String; }}

    internal override bool Peer {
      get {
        for (int i = 0; i < rgs.Count; i++)
          if (!((Expression) rgs [i]).Peer)
            return false;
        return true;
      }
    }
    
    public override object Evaluate (BaseIterator iter)
    {
      StringBuilder sb = new StringBuilder ();
      
      int len = rgs.Count;
      for (int i = 0; i < len; i++)
        sb.Append (((Expression)rgs[i]).EvaluateString (iter));
      
      return sb.ToString ();
    }

    public override string ToString ()
    {
      StringBuilder sb = new StringBuilder ();
      sb.Append ("concat(");
      for (int i = 0; i < rgs.Count - 1; i++) {
        sb.AppendFormat (CultureInfo.InvariantCulture, "{0}", rgs [i].ToString ());
        sb.Append (',');
      }
      sb.AppendFormat (CultureInfo.InvariantCulture, "{0}", rgs [rgs.Count - 1].ToString ());
      sb.Append (')');
      return sb.ToString ();
    }
  }


  internal class XPathFunctionStartsWith : XPathFunction
  {
    Expression arg0, arg1;
    
    public XPathFunctionStartsWith (FunctionArguments args) : base (args)
    {
      if (args == null || args.Tail == null || args.Tail.Tail != null)
        throw new XPathException ("starts-with takes 2 args");
      
      arg0 = args.Arg;
      arg1 = args.Tail.Arg;
    }
    
    public override XPathResultType ReturnType { get { return XPathResultType.Boolean; }}

    internal override bool Peer {
      get { return arg0.Peer && arg1.Peer; }
    }
    
    public override object Evaluate (BaseIterator iter)
    {
      return arg0.EvaluateString (iter).StartsWith (arg1.EvaluateString (iter));
    }

    public override string ToString ()
    {
      return String.Concat ("starts-with(", arg0.ToString (), ",", arg1.ToString (), ")");
    }
  }


  internal class XPathFunctionContains : XPathFunction
  {
    Expression arg0, arg1;
    
    public XPathFunctionContains (FunctionArguments args) : base (args)
    {
      if (args == null || args.Tail == null || args.Tail.Tail != null)
        throw new XPathException ("contains takes 2 args");
      
      arg0 = args.Arg;
      arg1 = args.Tail.Arg;
    }
    
    public override XPathResultType ReturnType { get { return XPathResultType.Boolean; }}

    internal override bool Peer {
      get { return arg0.Peer && arg1.Peer; }
    }
    
    public override object Evaluate (BaseIterator iter)
    {
      return arg0.EvaluateString (iter).IndexOf (arg1.EvaluateString (iter)) != -1;
    }

    public override string ToString ()
    {
      return String.Concat ("contains(", arg0.ToString (), ",", arg1.ToString (), ")");
    }
  }


  internal class XPathFunctionSubstringBefore : XPathFunction
  {
    Expression arg0, arg1;
    
    public XPathFunctionSubstringBefore (FunctionArguments args) : base (args)
    {
      if (args == null || args.Tail == null || args.Tail.Tail != null)
        throw new XPathException ("substring-before takes 2 args");
      
      arg0 = args.Arg;
      arg1 = args.Tail.Arg;
    }
    
    public override XPathResultType ReturnType { get { return XPathResultType.String; }}

    internal override bool Peer {
      get { return arg0.Peer && arg1.Peer; }
    }
    
    public override object Evaluate (BaseIterator iter)
    {
      string str1 = arg0.EvaluateString (iter);
      string str2 = arg1.EvaluateString (iter);
      int ich = str1.IndexOf (str2);
      if (ich <= 0)
        return "";
      return str1.Substring (0, ich);
    }

    public override string ToString ()
    {
      return String.Concat ("substring-before(", arg0.ToString (), ",", arg1.ToString (), ")");
    }
  }


  internal class XPathFunctionSubstringAfter : XPathFunction
  {
    Expression arg0, arg1;
    
    public XPathFunctionSubstringAfter (FunctionArguments args) : base (args)
    {
      if (args == null || args.Tail == null || args.Tail.Tail != null)
        throw new XPathException ("substring-after takes 2 args");
      
      arg0 = args.Arg;
      arg1 = args.Tail.Arg;
    }
    
    public override XPathResultType ReturnType { get { return XPathResultType.String; }}

    internal override bool Peer {
      get { return arg0.Peer && arg1.Peer; }
    }
    
    public override object Evaluate (BaseIterator iter)
    {
      string str1 = arg0.EvaluateString (iter);
      string str2 = arg1.EvaluateString (iter);
      int ich = str1.IndexOf (str2);
      if (ich < 0)
        return "";
      return str1.Substring (ich + str2.Length);
    }

    public override string ToString ()
    {
      return String.Concat ("substring-after(", arg0.ToString (), ",", arg1.ToString (), ")");
    }
  }


  internal class XPathFunctionSubstring : XPathFunction
  {
    Expression arg0, arg1, arg2;
    
    public XPathFunctionSubstring (FunctionArguments args) : base (args)
    {
      if (args == null || args.Tail == null || (args.Tail.Tail != null && args.Tail.Tail.Tail != null))
        throw new XPathException ("substring takes 2 or 3 args");
      
      arg0 = args.Arg;
      arg1 = args.Tail.Arg;
      if (args.Tail.Tail != null)
        arg2= args.Tail.Tail.Arg;
    }
    
    public override XPathResultType ReturnType { get { return XPathResultType.String; }}

    internal override bool Peer {
      get { return arg0.Peer && arg1.Peer && (arg2 != null ? arg2.Peer : true); }
    }
    
    public override object Evaluate (BaseIterator iter)
    {
      string str = arg0.EvaluateString (iter);
      double ich = Math.Round (arg1.EvaluateNumber (iter)) - 1;
      if (Double.IsNaN (ich) ||
        Double.IsNegativeInfinity (ich) ||
        ich >= (double) str.Length)
        return "";

      if (arg2 == null)
      {
        if (ich < 0)
          ich = 0.0;
        return str.Substring ((int) ich);
      }
      else
      {
        double cch = Math.Round (arg2.EvaluateNumber (iter));
        if (Double.IsNaN (cch))
          return "";
        if (ich < 0.0 || cch < 0.0) 
        {
          cch = ich + cch;
          if (cch <= 0.0)
            return "";
          ich = 0.0;
        }
        double cchMax = (double) str.Length - ich;
        if (cch > cchMax)
          cch = cchMax;
        return str.Substring ((int) ich, (int) cch);
      }
    }

    public override string ToString ()
    {
      return String.Concat (new string [] {
        "substring(", arg0.ToString (), ",", arg1.ToString (), ",", arg2.ToString (), ")"});
    }
  }


  internal class XPathFunctionStringLength : XPathFunction
  {
    Expression arg0;
    
    public XPathFunctionStringLength (FunctionArguments args) : base (args)
    {
      if (args != null) {
        arg0 = args.Arg;
        if (args.Tail != null)
          throw new XPathException ("string-length takes 1 or zero args");
      }
    }
    
    public override XPathResultType ReturnType { get { return XPathResultType.Number; }}

    internal override bool Peer {
      get { return arg0 != null ? arg0.Peer : true; }
    }
    
    public override object Evaluate (BaseIterator iter)
    {
      string str;
      if (arg0 != null)
        str = arg0.EvaluateString (iter);
      else
        str = iter.Current.Value;
      return (double) str.Length;
    }

    public override string ToString ()
    {
      return String.Concat (new string [] {
        "string-length(", arg0.ToString (), ")"});
    }
  }


  internal class XPathFunctionNormalizeSpace : XPathFunction
  {
    Expression arg0;
    
    public XPathFunctionNormalizeSpace (FunctionArguments args) : base (args)
    {
      if (args != null) {
        arg0 = args.Arg;
        if (args.Tail != null)
          throw new XPathException ("normalize-space takes 1 or zero args");
      }
    }
    
    public override XPathResultType ReturnType { get { return XPathResultType.String; }}

    internal override bool Peer {
      get { return arg0 !=null ? arg0.Peer : true; }
    }

    public override object Evaluate (BaseIterator iter)
    {
      string str;
      if (arg0 != null)
        str = arg0.EvaluateString (iter);
      else
        str = iter.Current.Value;
      System.Text.StringBuilder sb = new System.Text.StringBuilder ();
      bool fSpace = false;
      for (int i = 0; i < str.Length; i++) {
        char ch = str [i];
        if (ch == ' ' || ch == '\t' || ch == '\r' || ch == '\n')
        {
          fSpace = true;
        }
        else
        {
          if (fSpace)
          {
            fSpace = false;
            if (sb.Length > 0)
              sb.Append (' ');
          }
          sb.Append (ch);
        }
      }
      return sb.ToString ();
    }

    public override string ToString ()
    {
      return String.Concat (new string [] {
        "normalize-space(",
        arg0 != null ? arg0.ToString () : String.Empty,
        ")"});
    }
  }


  internal class XPathFunctionTranslate : XPathFunction
  {
    Expression arg0, arg1, arg2;
    
    public XPathFunctionTranslate (FunctionArguments args) : base (args)
    {
      if (args == null || args.Tail == null || args.Tail.Tail == null || args.Tail.Tail.Tail != null)
        throw new XPathException ("translate takes 3 args");
      
      arg0 = args.Arg;
      arg1 = args.Tail.Arg;
      arg2= args.Tail.Tail.Arg;
    }
    
    public override XPathResultType ReturnType { get { return XPathResultType.String; }}

    internal override bool Peer {
      get { return arg0.Peer && arg1.Peer && arg2.Peer; }
    }
    
    public override object Evaluate (BaseIterator iter)
    {
      string s0 = arg0.EvaluateString (iter);
      string s1 = arg1.EvaluateString (iter);
      string s2 = arg2.EvaluateString (iter);
      
      StringBuilder ret = new StringBuilder (s0.Length);
        
      int pos = 0, len = s0.Length, s2len = s2.Length;
      
      while (pos < len) {
        int idx = s1.IndexOf (s0 [pos]);
        
        if (idx != -1) {
          if (idx < s2len)
            ret.Append (s2 [idx]);
        }
        else
          ret.Append (s0 [pos]);
        
        pos++;
      }
      
      return ret.ToString ();
    }

    public override string ToString ()
    {
      return String.Concat (new string [] {
        "string-length(",
        arg0.ToString (), ",",
        arg1.ToString (), ",",
        arg2.ToString (), ")"});
    }
  }

  internal abstract class XPathBooleanFunction : XPathFunction
  {
    public XPathBooleanFunction (FunctionArguments args) : base (args)
    {
    }

    public override XPathResultType ReturnType { get { return XPathResultType.Boolean; }}

    public override object StaticValue {
      get { return StaticValueAsBoolean; }
    }
  }

  internal class XPathFunctionBoolean : XPathBooleanFunction
  {
    Expression arg0;
    
    public XPathFunctionBoolean (FunctionArguments args) : base (args)
    {
      if (args != null) {
        arg0 = args.Arg;
        if (args.Tail != null)
          throw new XPathException ("boolean takes 1 or zero args");
      }
    }
    
    internal override bool Peer {
      get { return arg0 != null ? arg0.Peer : true; }
    }

    public override object Evaluate (BaseIterator iter)
    {
      if (arg0 == null)
        return XPathFunctions.ToBoolean (iter.Current.Value);
      return arg0.EvaluateBoolean (iter);
    }

    public override string ToString ()
    {
      return String.Concat (new string [] {"boolean(", arg0.ToString (), ")"});
    }
  }


  internal class XPathFunctionNot : XPathBooleanFunction
  {
    Expression arg0;
    
    public XPathFunctionNot (FunctionArguments args) : base (args)
    {
      if (args == null || args.Tail != null)
        throw new XPathException ("not takes one arg");
      arg0 = args.Arg;
    }
    
    internal override bool Peer {
      get { return arg0.Peer; }
    }

    public override object Evaluate (BaseIterator iter)
    {
      return !arg0.EvaluateBoolean (iter);
    }

    public override string ToString ()
    {
      return String.Concat (new string [] {"not(", arg0.ToString (), ")"});
    }
  }


  internal class XPathFunctionTrue : XPathBooleanFunction
  {
    public XPathFunctionTrue (FunctionArguments args) : base (args)
    {
      if (args != null)
        throw new XPathException ("true takes 0 args");
    }

    public override bool HasStaticValue {
      get { return true; }
    }

    public override bool StaticValueAsBoolean {
      get { return true; }
    }
    
    internal override bool Peer {
      get { return true; }
    }

    public override object Evaluate (BaseIterator iter)
    {
      return true;
    }

    public override string ToString ()
    {
      return "true()";
    }
  }


  internal class XPathFunctionFalse : XPathBooleanFunction
  {
    public XPathFunctionFalse (FunctionArguments args) : base (args)
    {
      if (args != null)
        throw new XPathException ("false takes 0 args");
    }

    public override bool HasStaticValue {
      get { return true; }
    }

    public override bool StaticValueAsBoolean {
      get { return false; }
    }

    internal override bool Peer {
      get { return true; }
    }

    public override object Evaluate (BaseIterator iter)
    {
      return false;
    }

    public override string ToString ()
    {
      return "false()";
    }
  }


  internal class XPathFunctionLang : XPathFunction
  {
    Expression arg0;
    
    public XPathFunctionLang (FunctionArguments args) : base (args)
    {
      if (args == null || args.Tail != null)
        throw new XPathException ("lang takes one arg");
      arg0 = args.Arg;
    }

    public override XPathResultType ReturnType { get { return XPathResultType.Boolean; }}

    internal override bool Peer {
      get { return arg0.Peer; }
    }

    public override object Evaluate (BaseIterator iter)
    {
      return EvaluateBoolean (iter);
    }

    public override bool EvaluateBoolean (BaseIterator iter)
    {
      string lang = arg0.EvaluateString (iter).ToLower (CultureInfo.InvariantCulture);
      string actualLang = iter.Current.XmlLang.ToLower (CultureInfo.InvariantCulture);
      
      return lang == actualLang || lang == (actualLang.Split ('-')[0]);
    }

    public override string ToString ()
    {
      return String.Concat (new string [] {"lang(", arg0.ToString (), ")"});
    }
  }

  internal abstract class XPathNumericFunction : XPathFunction
  {
    internal XPathNumericFunction (FunctionArguments args)
      : base (args)
    {
    }

    public override XPathResultType ReturnType { get { return XPathResultType.Number; }}

    public override object StaticValue {
      get { return StaticValueAsNumber; }
    }
  }

  internal class XPathFunctionNumber : XPathNumericFunction
  {
    Expression arg0;
    
    public XPathFunctionNumber (FunctionArguments args) : base (args)
    {
      if (args != null) {
        arg0 = args.Arg;
        if (args.Tail != null)
          throw new XPathException ("number takes 1 or zero args");
      }
    }

    public override Expression Optimize ()
    {
      if (arg0 == null)
        return this;
      arg0 = arg0.Optimize ();
      return !arg0.HasStaticValue ?
        (Expression) this :
        new ExprNumber (StaticValueAsNumber);
    }

    public override bool HasStaticValue {
      get { return arg0 != null && arg0.HasStaticValue; }
    }

    public override double StaticValueAsNumber {
      get { return arg0 != null ? arg0.StaticValueAsNumber : 0; }
    }

    internal override bool Peer {
      get { return arg0 != null ? arg0.Peer : true; }
    }

    public override object Evaluate (BaseIterator iter)
    {
      if (arg0 == null)
        return XPathFunctions.ToNumber (iter.Current.Value);
      return arg0.EvaluateNumber (iter);
    }

    public override string ToString ()
    {
      return String.Concat (new string [] {"number(", arg0.ToString (), ")"});
    }
  }


  internal class XPathFunctionSum : XPathNumericFunction
  {
    Expression arg0;
    
    public XPathFunctionSum (FunctionArguments args) : base (args)
    {
      if (args == null || args.Tail != null)
        throw new XPathException ("sum takes one arg");
      arg0 = args.Arg;
    }
    
    internal override bool Peer {
      get { return arg0.Peer; }
    }

    public override object Evaluate (BaseIterator iter)
    {
      XPathNodeIterator itr = arg0.EvaluateNodeSet (iter);
      
      double sum = 0;
      while (itr.MoveNext ())
        sum += XPathFunctions.ToNumber (itr.Current.Value);
      
      return sum;
    }

    public override string ToString ()
    {
      return String.Concat (new string [] {"sum(", arg0.ToString (), ")"});
    }
  }


  internal class XPathFunctionFloor : XPathNumericFunction
  {
    Expression arg0;
    
    public XPathFunctionFloor (FunctionArguments args) : base (args)
    {
      if (args == null || args.Tail != null)
        throw new XPathException ("floor takes one arg");
      arg0 = args.Arg;
    }

    public override bool HasStaticValue {
      get { return arg0.HasStaticValue; }
    }

    public override double StaticValueAsNumber {
      get { return HasStaticValue ? Math.Floor (arg0.StaticValueAsNumber) : 0; }
    }
    
    internal override bool Peer {
      get { return arg0.Peer; }
    }

    public override object Evaluate (BaseIterator iter)
    {
      return Math.Floor (arg0.EvaluateNumber (iter));
    }

    public override string ToString ()
    {
      return String.Concat (new string [] {"floor(", arg0.ToString (), ")"});
    }
  }


  internal class XPathFunctionCeil : XPathNumericFunction
  {
    Expression arg0;
    
    public XPathFunctionCeil (FunctionArguments args) : base (args)
    {
      if (args == null || args.Tail != null)
        throw new XPathException ("ceil takes one arg");
      arg0 = args.Arg;
    }

    public override bool HasStaticValue {
      get { return arg0.HasStaticValue; }
    }

    public override double StaticValueAsNumber {
      get { return HasStaticValue ? Math.Ceiling (arg0.StaticValueAsNumber) : 0; }
    }
    
    internal override bool Peer {
      get { return arg0.Peer; }
    }

    public override object Evaluate (BaseIterator iter)
    {
      return Math.Ceiling (arg0.EvaluateNumber (iter));
    }

    public override string ToString ()
    {
      return String.Concat (new string [] {"ceil(", arg0.ToString (), ")"});
    }
  }


  internal class XPathFunctionRound : XPathNumericFunction
  {
    Expression arg0;
    
    public XPathFunctionRound (FunctionArguments args) : base (args)
    {
      if (args == null || args.Tail != null)
        throw new XPathException ("round takes one arg");
      arg0 = args.Arg;
    }
    
    public override bool HasStaticValue {
      get { return arg0.HasStaticValue; }
    }

    public override double StaticValueAsNumber {
      get { return HasStaticValue ? Round (arg0.StaticValueAsNumber) : 0; }
    }

    internal override bool Peer {
      get { return arg0.Peer; }
    }

    public override object Evaluate (BaseIterator iter)
    {
      return Round (arg0.EvaluateNumber (iter));
    }

    private double Round (double arg)
    {
      if (arg < -0.5 || arg > 0)
        return Math.Floor (arg + 0.5);
      return Math.Round (arg);
    }

    public override string ToString ()
    {
      return String.Concat (new string [] {"round(", arg0.ToString (), ")"});
    }
  }
}
www.java2v.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.