2002-06-23 Piers Haken <piersh@friskit.com>
[mono.git] / mcs / class / System.XML / System.Xml.XPath / DefaultContext.cs
1 //
2 // System.Xml.XPath.DefaultContext & support classes
3 //
4 // Author:
5 //   Piers Haken (piersh@friskit.com)
6 //
7 // (C) 2002 Piers Haken
8 //
9 using System;
10 using System.Collections;
11 using System.Xml;
12 using System.Xml.XPath;
13 using System.Xml.Xsl;
14
15 namespace System.Xml.XPath
16 {
17         /// <summary>
18         /// Summary description for DefaultContext.
19         /// </summary>
20         internal class DefaultContext : XsltContext
21         {
22                 protected static Hashtable _htFunctions = new Hashtable ();
23
24                 static DefaultContext()
25                 {
26                         Add (new XPathFunctionLast ());
27                         Add (new XPathFunctionPosition ());
28                         Add (new XPathFunctionCount ());
29                         Add (new XPathFunctionId ());
30                         Add (new XPathFunctionLocalName ());
31                         Add (new XPathFunctionNamespaceUri ());
32                         Add (new XPathFunctionName ());
33                         Add (new XPathFunctionString ());
34                         Add (new XPathFunctionConcat ());
35                         Add (new XPathFunctionStartsWith ());
36                         Add (new XPathFunctionContains ());
37                         Add (new XPathFunctionSubstringBefore ());
38                         Add (new XPathFunctionSubstringAfter ());
39                         Add (new XPathFunctionSubstring ());
40                         Add (new XPathFunctionStringLength ());
41                         Add (new XPathFunctionNormalizeSpace ());
42                         Add (new XPathFunctionTranslate ());
43                         Add (new XPathFunctionBoolean ());
44                         Add (new XPathFunctionNot ());
45                         Add (new XPathFunctionTrue ());
46                         Add (new XPathFunctionFalse ());
47                         Add (new XPathFunctionLang ());
48                         Add (new XPathFunctionNumber ());
49                         Add (new XPathFunctionSum ());
50                         Add (new XPathFunctionFloor ());
51                         Add (new XPathFunctionCeil ());
52                         Add (new XPathFunctionRound ());
53                 }
54
55                 [MonoTODO]
56                 public override IXsltContextFunction ResolveFunction (string prefix, string name, XPathResultType[] ArgTypes)
57                 {
58                         // match the prefix
59                         if (prefix != null && prefix != "")     // TODO: should we allow some namespaces here?
60                                 return null;
61
62                         // match the function name
63                         XPathFunction fn = (XPathFunction) _htFunctions [name];
64                         if (fn == null)
65                                 return null;
66
67                         // check the number of arguments
68                         int cArgs = ArgTypes.Length;
69                         if (cArgs < fn.Minargs || cArgs > fn.Maxargs)
70                                 return null;
71
72                         // check the types of the arguments
73                         XPathResultType [] rgTypes = fn.ArgTypes;
74                         if (rgTypes == null)
75                         {
76                                 if (cArgs != 0)
77                                         return null;
78                         }
79                         else
80                         {
81                                 int cTypes = rgTypes.Length;
82                                 for (int iArg = 0; iArg < cArgs; iArg ++)
83                                 {
84                                         XPathResultType typeRequested = ArgTypes [iArg];
85                                         XPathResultType typeDefined = (iArg >= cTypes) ? rgTypes [cTypes - 1] : rgTypes [iArg];
86                                         if (typeDefined != XPathResultType.Any && typeDefined != typeRequested)
87                                                 return null;
88                                 }
89                         }
90                         return fn;
91                 }
92                 public override IXsltContextVariable ResolveVariable (string prefix, string name)
93                 {
94                         return null;
95                 }
96                 [MonoTODO]
97                 public override int CompareDocument (string baseUri, string nextBaseUri) { throw new NotImplementedException (); }
98                 [MonoTODO]
99                 public override bool PreserveWhitespace (XPathNavigator nav) { throw new NotImplementedException (); }
100                 [MonoTODO]
101                 public override bool Whitespace { get { throw new NotImplementedException (); }}
102                 protected static void Add (XPathFunction fn)
103                 {
104                         _htFunctions.Add (fn.Name, fn);
105                 }
106         }
107
108         internal class XPathFunctions
109         {
110                 public static bool ToBoolean (object arg)
111                 {
112                         if (arg == null)
113                                 throw new ArgumentNullException ();
114                         if (arg is bool)
115                                 return (bool) arg;
116                         if (arg is double)
117                         {
118                                 double dArg = (double) arg;
119                                 return (dArg != 0.0 && !double.IsNaN (dArg));
120                         }
121                         if (arg is string)
122                                 return ((string) arg).Length != 0;
123                         if (arg is BaseIterator)
124                         {
125                                 BaseIterator iter = (BaseIterator) arg;
126                                 return iter.MoveNext ();
127                         }
128                         throw new ArgumentException ();
129                 }
130                 [MonoTODO]
131                 public static string ToString (object arg)
132                 {
133                         if (arg == null)
134                                 throw new ArgumentNullException ();
135                         if (arg is string)
136                                 return (string) arg;
137                         if (arg is bool)
138                                 return ((bool) arg) ? "true" : "false";
139                         if (arg is double)
140                                 return (string) XmlConvert.ToString ((double) arg);     // TODO: spec? convert number to string
141                         if (arg is BaseIterator)
142                         {
143                                 BaseIterator iter = (BaseIterator) arg;
144                                 if (!iter.MoveNext ())
145                                         return "";
146                                 return iter.Current.Value;
147                         }
148                         throw new ArgumentException ();
149                 }
150                 [MonoTODO]
151                 public static double ToNumber (object arg)
152                 {
153                         if (arg == null)
154                                 throw new ArgumentNullException ();
155                         if (arg is BaseIterator)
156                                 arg = ToString (arg);   // follow on
157                         if (arg is string)
158                                 return XmlConvert.ToDouble ((string) arg);      // TODO: spec? convert string to number
159                         if (arg is double)
160                                 return (double) arg;
161                         if (arg is bool)
162                                 return Convert.ToDouble ((bool) arg);
163                         throw new ArgumentException ();
164                 }
165         }
166
167         internal abstract class XPathFunction : IXsltContextFunction
168         {
169                 public abstract XPathResultType ReturnType { get; }
170                 public abstract int Minargs { get; }
171                 public abstract int Maxargs { get; }
172                 public abstract XPathResultType [] ArgTypes { get; }
173                 public object Invoke (XsltContext xsltContext, object[] args, XPathNavigator docContext)
174                 {
175                         return TypesafeInvoke (xsltContext, args, docContext);
176                 }
177
178                 public abstract string Name { get; }
179                 public abstract object TypesafeInvoke (XsltContext xsltContext, object[] args, XPathNavigator docContext);
180         }
181
182         internal class XPathFunctionLast : XPathFunction
183         {
184                 public override XPathResultType ReturnType { get { return XPathResultType.Number; }}
185                 public override int Minargs { get { return 0; }}
186                 public override int Maxargs { get { return 0; }}
187                 public override XPathResultType [] ArgTypes { get { return null; }}
188                 public override object TypesafeInvoke (XsltContext xsltContext, object[] args, XPathNavigator docContext)
189                 {
190                         throw new NotImplementedException ();   // special-cased
191                 }
192                 public override string Name { get { return "last"; }}
193         }
194         internal class XPathFunctionPosition : XPathFunction
195         {
196                 public override XPathResultType ReturnType { get { return XPathResultType.Number; }}
197                 public override int Minargs { get { return 0; }}
198                 public override int Maxargs { get { return 0; }}
199                 public override XPathResultType [] ArgTypes { get { return null; }}
200                 public override object TypesafeInvoke (XsltContext xsltContext, object[] args, XPathNavigator docContext)
201                 {
202                         throw new NotImplementedException ();   // special-cased
203                 }
204                 public override string Name { get { return "position"; }}
205         }
206         internal class XPathFunctionCount : XPathFunction
207         {
208                 public override XPathResultType ReturnType { get { return XPathResultType.Number; }}
209                 public override int Minargs { get { return 1; }}
210                 public override int Maxargs { get { return 1; }}
211                 public override XPathResultType [] ArgTypes { get { return new XPathResultType [] { XPathResultType.NodeSet }; }}
212                 public override object TypesafeInvoke (XsltContext xsltContext, object[] args, XPathNavigator docContext)
213                 {
214                         return ((BaseIterator) args [0]).Count;
215                 }
216                 public override string Name { get { return "count"; }}
217         }
218         internal class XPathFunctionId : XPathFunction
219         {
220                 public override XPathResultType ReturnType { get { return XPathResultType.Number; }}
221                 public override int Minargs { get { return 1; }}
222                 public override int Maxargs { get { return 1; }}
223                 public override XPathResultType [] ArgTypes { get { return new XPathResultType [] { XPathResultType.Any }; }}
224                 [MonoTODO]
225                 public override object TypesafeInvoke (XsltContext xsltContext, object[] args, XPathNavigator docContext)
226                 {
227                         throw new NotImplementedException ();
228                 }
229                 public override string Name { get { return "id"; }}
230         }
231         internal class XPathFunctionLocalName : XPathFunction
232         {
233                 public override XPathResultType ReturnType { get { return XPathResultType.NodeSet; }}
234                 public override int Minargs { get { return 0; }}
235                 public override int Maxargs { get { return 1; }}
236                 public override XPathResultType [] ArgTypes { get { return new XPathResultType [] { XPathResultType.NodeSet }; }}
237                 public override object TypesafeInvoke (XsltContext xsltContext, object[] args, XPathNavigator docContext)
238                 {
239                         BaseIterator iter = (args.Length == 1) ? ((BaseIterator) args [0]) : new SelfIterator (docContext, xsltContext);
240                         if (iter == null || !iter.MoveNext ())
241                                 return "";
242                         return iter.Current.LocalName;
243                 }
244                 public override string Name { get { return "local-name"; }}
245         }
246         internal class XPathFunctionNamespaceUri : XPathFunction
247         {
248                 public override XPathResultType ReturnType { get { return XPathResultType.String; }}
249                 public override int Minargs { get { return 0; }}
250                 public override int Maxargs { get { return 1; }}
251                 public override XPathResultType [] ArgTypes { get { return new XPathResultType [] { XPathResultType.NodeSet }; }}
252                 [MonoTODO]
253                 public override object TypesafeInvoke (XsltContext xsltContext, object[] args, XPathNavigator docContext)
254                 {
255                         BaseIterator iter = (args.Length == 1) ? ((BaseIterator) args [0]) : new SelfIterator (docContext, xsltContext);
256                         if (iter == null || !iter.MoveNext ())
257                                 return "";
258                         return iter.Current.NamespaceURI;       // TODO: should the namespace be expanded wrt. the given context?
259                 }
260                 public override string Name { get { return "namespace-uri"; }}
261         }
262         internal class XPathFunctionName : XPathFunction
263         {
264                 public override XPathResultType ReturnType { get { return XPathResultType.String; }}
265                 public override int Minargs { get { return 0; }}
266                 public override int Maxargs { get { return 1; }}
267                 public override XPathResultType [] ArgTypes { get { return new XPathResultType [] { XPathResultType.NodeSet }; }}
268                 [MonoTODO]
269                 public override object TypesafeInvoke (XsltContext xsltContext, object[] args, XPathNavigator docContext)
270                 {
271                         throw new NotImplementedException ();
272                 }
273                 public override string Name { get { return "name"; }}
274         }
275         internal class XPathFunctionString : XPathFunction
276         {
277                 public override XPathResultType ReturnType { get { return XPathResultType.String; }}
278                 public override int Minargs { get { return 0; }}
279                 public override int Maxargs { get { return 1; }}
280                 public override XPathResultType [] ArgTypes { get { return new XPathResultType [] { XPathResultType.Any }; }}
281                 public override object TypesafeInvoke (XsltContext xsltContext, object[] args, XPathNavigator docContext)
282                 {
283                         return XPathFunctions.ToString (args [0]);
284                 }
285                 public override string Name { get { return "string"; }}
286         }
287         internal class XPathFunctionConcat : XPathFunction
288         {
289                 public override XPathResultType ReturnType { get { return XPathResultType.String; }}
290                 public override int Minargs { get { return 2; }}
291                 public override int Maxargs { get { return int.MaxValue; }}
292                 public override XPathResultType [] ArgTypes { get { return new XPathResultType [] { XPathResultType.String, XPathResultType.String, XPathResultType.String }; }}
293                 public override object TypesafeInvoke (XsltContext xsltContext, object[] args, XPathNavigator docContext)
294                 {
295                         String str = "";
296                         foreach (string strArg in args)
297                                 str += strArg;
298                         return str;
299                 }
300                 public override string Name { get { return "concat"; }}
301         }
302         internal class XPathFunctionStartsWith : XPathFunction
303         {
304                 public override XPathResultType ReturnType { get { return XPathResultType.Boolean; }}
305                 public override int Minargs { get { return 2; }}
306                 public override int Maxargs { get { return 2; }}
307                 public override XPathResultType [] ArgTypes { get { return new XPathResultType [] { XPathResultType.String, XPathResultType.String }; }}
308                 public override object TypesafeInvoke (XsltContext xsltContext, object[] args, XPathNavigator docContext)
309                 {
310                         string str1 = (string) args [0];
311                         string str2 = (string) args [1];
312                         return str1.StartsWith (str2);
313                 }
314                 public override string Name { get { return "starts-with"; }}
315         }
316         internal class XPathFunctionContains : XPathFunction
317         {
318                 public override XPathResultType ReturnType { get { return XPathResultType.Boolean; }}
319                 public override int Minargs { get { return 2; }}
320                 public override int Maxargs { get { return 2; }}
321                 public override XPathResultType [] ArgTypes { get { return new XPathResultType [] { XPathResultType.String, XPathResultType.String }; }}
322                 public override object TypesafeInvoke (XsltContext xsltContext, object[] args, XPathNavigator docContext)
323                 {
324                         string str1 = (string) args [0];
325                         string str2 = (string) args [1];
326                         return str1.IndexOf (str2) != -1;
327                 }
328                 public override string Name { get { return "contains"; }}
329         }
330         internal class XPathFunctionSubstringBefore : XPathFunction
331         {
332                 public override XPathResultType ReturnType { get { return XPathResultType.String; }}
333                 public override int Minargs { get { return 2; }}
334                 public override int Maxargs { get { return 2; }}
335                 public override XPathResultType [] ArgTypes { get { return new XPathResultType [] { XPathResultType.String, XPathResultType.String }; }}
336                 public override object TypesafeInvoke (XsltContext xsltContext, object[] args, XPathNavigator docContext)
337                 {
338                         string str1 = (string) args [0];
339                         string str2 = (string) args [1];
340                         int ich = str1.IndexOf (str2);
341                         if (ich <= 0)
342                                 return "";
343                         return str1.Substring (0, ich);
344                 }
345                 public override string Name { get { return "substring-before"; }}
346         }
347         internal class XPathFunctionSubstringAfter : XPathFunction
348         {
349                 public override XPathResultType ReturnType { get { return XPathResultType.String; }}
350                 public override int Minargs { get { return 2; }}
351                 public override int Maxargs { get { return 2; }}
352                 public override XPathResultType [] ArgTypes { get { return new XPathResultType [] { XPathResultType.String, XPathResultType.String }; }}
353                 public override object TypesafeInvoke (XsltContext xsltContext, object[] args, XPathNavigator docContext)
354                 {
355                         string str1 = (string) args [0];
356                         string str2 = (string) args [1];
357                         int ich = str1.IndexOf (str2);
358                         if (ich <= 0)
359                                 return "";
360                         return str1.Substring (ich + str2.Length);
361                 }
362                 public override string Name { get { return "substring-after"; }}
363         }
364         internal class XPathFunctionSubstring : XPathFunction
365         {
366                 public override XPathResultType ReturnType { get { return XPathResultType.String; }}
367                 public override int Minargs { get { return 2; }}
368                 public override int Maxargs { get { return int.MaxValue; }}
369                 public override XPathResultType [] ArgTypes { get { return new XPathResultType [] { XPathResultType.String, XPathResultType.String, XPathResultType.String }; }}
370                 [MonoTODO]
371                 public override object TypesafeInvoke (XsltContext xsltContext, object[] args, XPathNavigator docContext)
372                 {
373                         // TODO: check this, what the hell were they smoking?
374                         string str = (string) args [0];
375                         double ich = Math.Round ((double) args [1]) - 1;
376                         if (Double.IsNaN (ich) || ich >= (double) str.Length)
377                                 return "";
378
379                         if (args.Length == 2)
380                         {
381                                 if (ich < 0)
382                                         ich = 0.0;
383                                 return str.Substring ((int) ich);
384                         }
385                         else
386                         {
387                                 double cch = Math.Round ((double) args [2]);
388                                 if (Double.IsNaN (cch))
389                                         return "";
390                                 if (ich < 0.0 || cch < 0.0) 
391                                 {
392                                         cch = ich + cch;
393                                         if (cch <= 0.0)
394                                                 return "";
395                                         ich = 0.0;
396                                 }
397                                 double cchMax = (double) str.Length - ich;
398                                 if (cch > cchMax)
399                                         cch = cchMax;
400                                 return str.Substring ((int) ich, (int) cch);
401                         }
402                 }
403                 public override string Name { get { return "substring"; }}
404         }
405         internal class XPathFunctionStringLength : XPathFunction
406         {
407                 public override XPathResultType ReturnType { get { return XPathResultType.Number; }}
408                 public override int Minargs { get { return 0; }}
409                 public override int Maxargs { get { return 1; }}
410                 public override XPathResultType [] ArgTypes { get { return new XPathResultType [] { XPathResultType.String }; }}
411                 public override object TypesafeInvoke (XsltContext xsltContext, object[] args, XPathNavigator docContext)
412                 {
413                         return (double) ((string) args [0]).Length;
414                 }
415                 public override string Name { get { return "string-length"; }}
416         }
417         internal class XPathFunctionNormalizeSpace : XPathFunction
418         {
419                 public override XPathResultType ReturnType { get { return XPathResultType.String; }}
420                 public override int Minargs { get { return 0; }}
421                 public override int Maxargs { get { return 1; }}
422                 public override XPathResultType [] ArgTypes { get { return new XPathResultType [] { XPathResultType.String }; }}
423                 [MonoTODO]
424                 public override object TypesafeInvoke (XsltContext xsltContext, object[] args, XPathNavigator docContext)
425                 {
426                         throw new NotImplementedException ();
427                 }
428                 public override string Name { get { return "normalize-sace"; }}
429         }
430         internal class XPathFunctionTranslate : XPathFunction
431         {
432                 public override XPathResultType ReturnType { get { return XPathResultType.String; }}
433                 public override int Minargs { get { return 3; }}
434                 public override int Maxargs { get { return 3; }}
435                 public override XPathResultType [] ArgTypes { get { return new XPathResultType [] { XPathResultType.String, XPathResultType.String, XPathResultType.String }; }}
436                 [MonoTODO]
437                 public override object TypesafeInvoke (XsltContext xsltContext, object[] args, XPathNavigator docContext)
438                 {
439                         throw new NotImplementedException ();
440                 }
441                 public override string Name { get { return "translate"; }}
442         }
443         internal class XPathFunctionBoolean : XPathFunction
444         {
445                 public override XPathResultType ReturnType { get { return XPathResultType.Boolean; }}
446                 public override int Minargs { get { return 1; }}
447                 public override int Maxargs { get { return 1; }}
448                 public override XPathResultType [] ArgTypes { get { return new XPathResultType [] { XPathResultType.Any }; }}
449                 public override object TypesafeInvoke (XsltContext xsltContext, object[] args, XPathNavigator docContext)
450                 {
451                         return XPathFunctions.ToBoolean (args [0]);
452                 }
453                 public override string Name { get { return "boolean"; }}
454         }
455         internal class XPathFunctionNot : XPathFunction
456         {
457                 public override XPathResultType ReturnType { get { return XPathResultType.Boolean; }}
458                 public override int Minargs { get { return 1; }}
459                 public override int Maxargs { get { return 1; }}
460                 public override XPathResultType [] ArgTypes { get { return new XPathResultType [] { XPathResultType.Boolean }; }}
461                 public override object TypesafeInvoke (XsltContext xsltContext, object[] args, XPathNavigator docContext)
462                 {
463                         return !((bool) args [0]);
464                 }
465                 public override string Name { get { return "not"; }}
466         }
467         internal class XPathFunctionTrue : XPathFunction
468         {
469                 public override XPathResultType ReturnType { get { return XPathResultType.Boolean; }}
470                 public override int Minargs { get { return 0; }}
471                 public override int Maxargs { get { return 0; }}
472                 public override XPathResultType [] ArgTypes { get { return null; }}
473                 public override object TypesafeInvoke (XsltContext xsltContext, object[] args, XPathNavigator docContext)
474                 {
475                         return true;
476                 }
477                 public override string Name { get { return "true"; }}
478         }
479         internal class XPathFunctionFalse : XPathFunction
480         {
481                 public override XPathResultType ReturnType { get { return XPathResultType.Boolean; }}
482                 public override int Minargs { get { return 0; }}
483                 public override int Maxargs { get { return 0; }}
484                 public override XPathResultType [] ArgTypes { get { return null; }}
485                 public override object TypesafeInvoke (XsltContext xsltContext, object[] args, XPathNavigator docContext)
486                 {
487                         return false;
488                 }
489                 public override string Name { get { return "false"; }}
490         }
491         internal class XPathFunctionLang : XPathFunction
492         {
493                 public override XPathResultType ReturnType { get { return XPathResultType.Boolean; }}
494                 public override int Minargs { get { return 1; }}
495                 public override int Maxargs { get { return 1; }}
496                 public override XPathResultType [] ArgTypes { get { return new XPathResultType [] { XPathResultType.String }; }}
497                 [MonoTODO]
498                 public override object TypesafeInvoke (XsltContext xsltContext, object[] args, XPathNavigator docContext)
499                 {
500                         throw new NotImplementedException ();
501                 }
502                 public override string Name { get { return "lang"; }}
503         }
504         internal class XPathFunctionNumber : XPathFunction
505         {
506                 public override XPathResultType ReturnType { get { return XPathResultType.Number; }}
507                 public override int Minargs { get { return 0; }}
508                 public override int Maxargs { get { return 1; }}
509                 public override XPathResultType [] ArgTypes { get { return new XPathResultType [] { XPathResultType.Any }; }}
510                 public override object TypesafeInvoke (XsltContext xsltContext, object[] args, XPathNavigator docContext)
511                 {
512                         return XPathFunctions.ToNumber (args [0]);
513                 }
514                 public override string Name { get { return "number"; }}
515         }
516         internal class XPathFunctionSum : XPathFunction
517         {
518                 public override XPathResultType ReturnType { get { return XPathResultType.Number; }}
519                 public override int Minargs { get { return 1; }}
520                 public override int Maxargs { get { return 1; }}
521                 public override XPathResultType [] ArgTypes { get { return new XPathResultType [] { XPathResultType.NodeSet }; }}
522                 [MonoTODO]
523                 public override object TypesafeInvoke (XsltContext xsltContext, object[] args, XPathNavigator docContext)
524                 {
525                         throw new NotImplementedException ();
526                 }
527                 public override string Name { get { return "sum"; }}
528         }
529         internal class XPathFunctionFloor : XPathFunction
530         {
531                 public override XPathResultType ReturnType { get { return XPathResultType.Number; }}
532                 public override int Minargs { get { return 1; }}
533                 public override int Maxargs { get { return 1; }}
534                 public override XPathResultType [] ArgTypes { get { return new XPathResultType [] { XPathResultType.Number }; }}
535                 public override object TypesafeInvoke (XsltContext xsltContext, object[] args, XPathNavigator docContext)
536                 {
537                         return Math.Floor ((double) args [0]);
538                 }
539                 public override string Name { get { return "floor"; }}
540         }
541         internal class XPathFunctionCeil : XPathFunction
542         {
543                 public override XPathResultType ReturnType { get { return XPathResultType.Number; }}
544                 public override int Minargs { get { return 1; }}
545                 public override int Maxargs { get { return 1; }}
546                 public override XPathResultType [] ArgTypes { get { return new XPathResultType [] { XPathResultType.Number }; }}
547                 public override object TypesafeInvoke (XsltContext xsltContext, object[] args, XPathNavigator docContext)
548                 {
549                         return Math.Ceiling ((double) args [0]);
550                 }
551                 public override string Name { get { return "ceil"; }}
552         }
553         internal class XPathFunctionRound : XPathFunction
554         {
555                 public override XPathResultType ReturnType { get { return XPathResultType.Number; }}
556                 public override int Minargs { get { return 1; }}
557                 public override int Maxargs { get { return 1; }}
558                 public override XPathResultType [] ArgTypes { get { return new XPathResultType [] { XPathResultType.Number }; }}
559                 public override object TypesafeInvoke (XsltContext xsltContext, object[] args, XPathNavigator docContext)
560                 {
561                         double arg = (double) args [0];
562                         if (arg < -0.5 || arg > 0)
563                                 return Math.Floor (arg + 0.5);
564                         return Math.Round (arg);
565                 }
566                 public override string Name { get { return "round"; }}
567         }
568 }