2 // System.Xml.Query.XQueryConvert
5 // Atsushi Enomoto <atsushi@ximian.com>
7 // Copyright (C) 2004 Novell Inc.
11 // Permission is hereby granted, free of charge, to any person obtaining
12 // a copy of this software and associated documentation files (the
13 // "Software"), to deal in the Software without restriction, including
14 // without limitation the rights to use, copy, modify, merge, publish,
15 // distribute, sublicense, and/or sell copies of the Software, and to
16 // permit persons to whom the Software is furnished to do so, subject to
17 // the following conditions:
19 // The above copyright notice and this permission notice shall be
20 // included in all copies or substantial portions of the Software.
22 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
23 // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
24 // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
25 // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
26 // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
27 // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
28 // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
32 using System.Globalization;
36 using System.Xml.Schema;
37 using System.Xml.XPath;
41 internal class XQueryConvert // Won't be public in the final stage
44 public static bool ShouldCheckValueFacets (XmlSchemaType schemaTypeDest)
46 throw new NotImplementedException ();
49 public static XmlTypeCode GetFallbackType (XmlTypeCode type)
52 case XmlTypeCode.AnyAtomicType:
53 return XmlTypeCode.Item;
54 case XmlTypeCode.UntypedAtomic:
55 return XmlTypeCode.String;
56 case XmlTypeCode.Notation:
57 return XmlTypeCode.QName;
58 case XmlTypeCode.NormalizedString:
59 case XmlTypeCode.Token:
60 case XmlTypeCode.Language:
61 case XmlTypeCode.NmToken:
62 case XmlTypeCode.Name:
63 case XmlTypeCode.NCName:
65 case XmlTypeCode.Idref:
66 case XmlTypeCode.Entity:
67 return XmlTypeCode.String;
68 case XmlTypeCode.NonPositiveInteger:
69 return XmlTypeCode.Decimal;
70 case XmlTypeCode.NegativeInteger:
71 return XmlTypeCode.NonPositiveInteger;
72 case XmlTypeCode.Long:
73 return XmlTypeCode.Integer;
74 case XmlTypeCode.Short:
75 return XmlTypeCode.Int;
76 case XmlTypeCode.Byte:
77 return XmlTypeCode.Int;
78 case XmlTypeCode.NonNegativeInteger:
79 return XmlTypeCode.Decimal;
80 case XmlTypeCode.UnsignedLong:
81 return XmlTypeCode.NonNegativeInteger;
82 case XmlTypeCode.UnsignedInt:
83 return XmlTypeCode.Integer;
84 case XmlTypeCode.UnsignedShort:
85 return XmlTypeCode.Int;
86 case XmlTypeCode.UnsignedByte:
87 return XmlTypeCode.UnsignedShort;
88 case XmlTypeCode.PositiveInteger:
89 return XmlTypeCode.NonNegativeInteger;
91 return XmlTypeCode.None;
96 // See XQuery & XPath 2.0 functions & operators section 17.
97 public static bool CanConvert (XPathItem item, XmlSchemaType schemaTypeDest)
100 throw new ArgumentNullException ("item");
101 if (schemaTypeDest == null)
102 throw new ArgumentNullException ("schemaTypeDest");
103 XmlTypeCode src = item.XmlType.TypeCode;
104 XmlTypeCode dst = schemaTypeDest.TypeCode;
106 // Notation cannot be converted from other than Notation
107 if (src == XmlTypeCode.Notation && dst != XmlTypeCode.Notation)
110 // untypedAtomic and string are convertable unless source type is QName.
112 case XmlTypeCode.UntypedAtomic:
113 case XmlTypeCode.String:
114 return src != XmlTypeCode.QName;
118 case XmlTypeCode.None:
119 case XmlTypeCode.Item:
120 case XmlTypeCode.Node:
121 case XmlTypeCode.Document:
122 case XmlTypeCode.Element:
123 case XmlTypeCode.Attribute:
124 case XmlTypeCode.Namespace:
125 case XmlTypeCode.ProcessingInstruction:
126 case XmlTypeCode.Comment:
127 case XmlTypeCode.Text:
128 throw new NotImplementedException (); // FIXME: check what happens
130 case XmlTypeCode.AnyAtomicType:
131 throw new NotImplementedException (); // FIXME: check what happens
132 case XmlTypeCode.UntypedAtomic:
133 case XmlTypeCode.String:
135 throw new NotImplementedException (); // FIXME: check what happens
137 case XmlTypeCode.Boolean:
138 case XmlTypeCode.Decimal:
140 case XmlTypeCode.Float:
141 case XmlTypeCode.Double:
142 case XmlTypeCode.Decimal:
143 case XmlTypeCode.Boolean:
148 case XmlTypeCode.Float:
149 case XmlTypeCode.Double:
150 if (dst == XmlTypeCode.Decimal)
152 throw new NotImplementedException (); // FIXME: check what happens
153 goto case XmlTypeCode.Decimal;
155 case XmlTypeCode.Duration:
157 case XmlTypeCode.Duration:
158 case XmlTypeCode.YearMonthDuration:
159 case XmlTypeCode.DayTimeDuration:
164 case XmlTypeCode.DateTime:
166 case XmlTypeCode.DateTime:
167 case XmlTypeCode.Time:
168 case XmlTypeCode.Date:
169 case XmlTypeCode.GYearMonth:
170 case XmlTypeCode.GYear:
171 case XmlTypeCode.GMonthDay:
172 case XmlTypeCode.GDay:
173 case XmlTypeCode.GMonth:
178 case XmlTypeCode.Time:
180 case XmlTypeCode.Time:
181 case XmlTypeCode.Date:
186 case XmlTypeCode.Date:
187 if (dst == XmlTypeCode.Time)
189 goto case XmlTypeCode.DateTime;
191 case XmlTypeCode.GYearMonth:
192 case XmlTypeCode.GYear:
193 case XmlTypeCode.GMonthDay:
194 case XmlTypeCode.GDay:
195 case XmlTypeCode.GMonth:
198 case XmlTypeCode.HexBinary:
199 case XmlTypeCode.Base64Binary:
203 case XmlTypeCode.HexBinary:
204 case XmlTypeCode.Base64Binary:
209 case XmlTypeCode.AnyUri:
210 case XmlTypeCode.QName:
211 case XmlTypeCode.Notation:
214 case XmlTypeCode.NormalizedString:
215 case XmlTypeCode.Token:
216 case XmlTypeCode.Language:
217 case XmlTypeCode.NmToken:
218 case XmlTypeCode.Name:
219 case XmlTypeCode.NCName:
221 case XmlTypeCode.Idref:
222 case XmlTypeCode.Entity:
223 case XmlTypeCode.Integer:
224 case XmlTypeCode.NonPositiveInteger:
225 case XmlTypeCode.NegativeInteger:
226 case XmlTypeCode.Long:
227 case XmlTypeCode.Int:
228 case XmlTypeCode.Short:
229 case XmlTypeCode.Byte:
230 case XmlTypeCode.NonNegativeInteger:
231 case XmlTypeCode.UnsignedLong:
232 case XmlTypeCode.UnsignedInt:
233 case XmlTypeCode.UnsignedShort:
234 case XmlTypeCode.UnsignedByte:
235 case XmlTypeCode.PositiveInteger:
236 throw new NotImplementedException ();
239 case XmlTypeCode.YearMonthDuration:
240 if (dst == XmlTypeCode.DayTimeDuration)
242 goto case XmlTypeCode.Duration;
243 case XmlTypeCode.DayTimeDuration:
244 if (dst == XmlTypeCode.YearMonthDuration)
246 goto case XmlTypeCode.Duration;
249 throw new NotImplementedException ();
252 // Individual conversion
254 public static string AnyUriToString (string value)
259 public static byte [] Base64BinaryToHexBinary (byte [] value)
261 return XmlConvert.FromBinHexString (Convert.ToBase64String (value));
264 public static string Base64BinaryToString (byte [] value)
266 return Convert.ToBase64String (value);
269 public static decimal BooleanToDecimal (bool value)
271 return Convert.ToDecimal (value);
274 public static double BooleanToDouble (bool value)
276 return Convert.ToDouble (value);
279 public static float BooleanToFloat (bool value)
281 return Convert.ToSingle (value);
284 public static int BooleanToInt (bool value)
286 return Convert.ToInt32 (value);
289 public static long BooleanToInteger (bool value)
291 return Convert.ToInt64 (value);
294 public static string BooleanToString (bool value)
296 // It looks not returning "True"
297 return value ? "true" : "false";
301 public static DateTime DateTimeToDate (DateTime value)
307 public static DateTime DateTimeToGDay (DateTime value)
309 return new DateTime (0, 0, value.Day);
313 public static DateTime DateTimeToGMonth (DateTime value)
315 return new DateTime (0, value.Month, 0);
319 public static DateTime DateTimeToGYear (DateTime value)
321 return new DateTime (value.Year, 0, 0);
325 public static DateTime DateTimeToGYearMonth (DateTime value)
327 return new DateTime (value.Year, value.Month, 0);
331 public static DateTime DateToDateTime (DateTime value)
337 public static DateTime DateToGDay (DateTime value)
339 return new DateTime (0, 0, value.Day);
343 public static DateTime DateToGMonth (DateTime value)
345 return new DateTime (0, value.Month, 0);
349 public static DateTime DateToGYear (DateTime value)
351 return new DateTime (value.Year, 0, 0);
355 public static DateTime DateToGYearMonth (DateTime value)
357 return new DateTime (value.Year, value.Month, 0);
361 public static string DateToString (DateTime value)
363 return XmlConvert.ToString (value);
367 public static string DateTimeToString (DateTime value)
369 return XmlConvert.ToString (value);
373 public static string DayTimeDurationToDuration (TimeSpan value)
375 return XmlConvert.ToString (value);
379 public static string DayTimeDurationToString (TimeSpan value)
381 return DayTimeDurationToDuration (value);
385 public static bool DecimalToBoolean (decimal value)
391 public static double DecimalToDouble (decimal value)
393 return (double) value;
397 public static float DecimalToFloat (decimal value)
399 return (float) value;
403 public static int DecimalToInt (decimal value)
409 public static long DecimalToInteger (decimal value)
414 [MonoTODO] // what if value was negative?
415 public static decimal DecimalToNonNegativeInteger (decimal value)
417 throw new NotImplementedException ();
420 [MonoTODO] // what if value was positive?
421 public static decimal DecimalToNonPositiveInteger (decimal value)
423 throw new NotImplementedException ();
427 public static string DecimalToString (decimal value)
429 return XmlConvert.ToString (value);
433 public static bool DoubleToBoolean (double value)
439 public static decimal DoubleToDecimal (double value)
441 return (decimal) value;
445 public static float DoubleToFloat (double value)
447 return (float) value;
451 public static int DoubleToInt (double value)
457 public static long DoubleToInteger (double value)
462 [MonoTODO] // what if value was negative?
463 public static decimal DoubleToNonNegativeInteger (double value)
465 throw new NotImplementedException ();
468 [MonoTODO] // what if value was positive?
469 public static decimal DoubleToNonPositiveInteger (double value)
471 throw new NotImplementedException ();
475 public static string DoubleToString (double value)
477 return XmlConvert.ToString (value);
481 public static TimeSpan DurationToDayTimeDuration (string value)
483 return XmlConvert.ToTimeSpan (value);
487 public static string DurationToString (string value)
489 return XmlConvert.ToString (XmlConvert.ToTimeSpan (value));
493 public static TimeSpan DurationToYearMonthDuration (string value)
495 return XmlConvert.ToTimeSpan (value);
500 public static bool FloatToBoolean (float value)
506 public static decimal FloatToDecimal (float value)
508 return (decimal) value;
512 public static double FloatToDouble (float value)
514 return (double) value;
518 public static int FloatToInt (float value)
524 public static long FloatToInteger (float value)
529 [MonoTODO] // what if value was negative?
530 public static decimal FloatToNonNegativeInteger (float value)
532 throw new NotImplementedException ();
535 [MonoTODO] // what if value was positive?
536 public static decimal FloatToNonPositiveInteger (float value)
538 throw new NotImplementedException ();
542 public static string FloatToString (float value)
544 return XmlConvert.ToString (value);
548 public static string GDayToString (DateTime value)
550 return XmlConvert.ToString (TimeSpan.FromDays (value.Day));
554 public static string GMonthDayToString (DateTime value)
556 return XmlConvert.ToString (new TimeSpan (value.Day, value.Hour, value.Minute, value.Second));
560 public static string GMonthToString (DateTime value)
562 return XmlConvert.ToString (new TimeSpan (0, value.Month, 0));
566 public static string GYearMonthToString (DateTime value)
568 return XmlConvert.ToString (new TimeSpan (value.Year, value.Month, 0));
572 public static string GYearToString (DateTime value)
574 return XmlConvert.ToString (new TimeSpan (new DateTime (value.Year, 0, 0).Ticks));
577 public static string HexBinaryToString (byte [] data)
579 return XmlConvert.ToBinHexString (data);
582 public static string HexBinaryToBase64String (byte [] data)
584 return XmlConvert.ToBinHexString (data);
589 public static bool IntegerToBoolean (long value)
595 public static decimal IntegerToDecimal (long value)
597 return (decimal) value;
601 public static double IntegerToDouble (long value)
603 return (double) value;
607 public static float IntegerToFloat (long value)
609 return (float) value;
613 public static int IntegerToInt (long value)
619 public static string IntegerToString (long value)
621 return XmlConvert.ToString (value);
625 public static bool IntToBoolean (int value)
631 public static decimal IntToDecimal (int value)
633 return (decimal) value;
637 public static double IntToDouble (int value)
639 return (double) value;
643 public static float IntToFloat (int value)
645 return (float) value;
649 public static long IntToInteger (int value)
655 public static string IntToString (int value)
657 return XmlConvert.ToString (value);
661 public static string NonNegativeIntegerToString (decimal value)
663 return XmlConvert.ToString (value);
667 public static string NonPositiveIntegerToString (decimal value)
669 return XmlConvert.ToString (value);
673 public static DateTime TimeToDateTime (DateTime value)
679 public static string TimeToString (DateTime value)
681 return XmlConvert.ToString (value, "HH:mm:ssZ");
685 public static string YearMonthDurationToDuration (TimeSpan value)
687 return XmlConvert.ToString (value);
691 public static string YearMonthDurationToString (TimeSpan value)
693 return YearMonthDurationToDuration (value);
697 public static string StringToAnyUri (string value)
703 public static byte [] StringToBase64Binary (string value)
705 return Convert.FromBase64String (value);
709 public static bool StringToBoolean (string value)
711 return XmlConvert.ToBoolean (value);
715 public static DateTime StringToDate (string value)
717 return XmlConvert.ToDateTime (value);
721 public static DateTime StringToDateTime (string value)
723 return XmlConvert.ToDateTime (value);
727 public static TimeSpan StringToDayTimeDuration (string value)
729 return XmlConvert.ToTimeSpan (value);
733 public static decimal StringToDecimal (string value)
735 return XmlConvert.ToDecimal (value);
739 public static double StringToDouble (string value)
741 return XmlConvert.ToDouble (value);
745 public static string StringToDuration (string value)
747 return XmlConvert.ToString (XmlConvert.ToTimeSpan (value));
751 public static float StringToFloat (string value)
753 return XmlConvert.ToSingle (value);
757 public static DateTime StringToGDay (string value)
759 return XmlConvert.ToDateTime (value);
763 public static DateTime StringToGMonth (string value)
765 return XmlConvert.ToDateTime (value);
769 public static DateTime StringToGMonthDay (string value)
771 return XmlConvert.ToDateTime (value);
775 public static DateTime StringToGYear (string value)
777 return XmlConvert.ToDateTime (value);
781 public static DateTime StringToGYearMonth (string value)
783 return XmlConvert.ToDateTime (value);
787 public static byte [] StringToHexBinary (string value)
789 return XmlConvert.FromBinHexString (value);
793 public static int StringToInt (string value)
795 return XmlConvert.ToInt32 (value);
799 public static long StringToInteger (string value)
801 return XmlConvert.ToInt64 (value);
805 public static decimal StringToNonNegativeInteger (string value)
807 return XmlConvert.ToDecimal (value);
811 public static decimal StringToNonPositiveInteger (string value)
813 return XmlConvert.ToDecimal (value);
817 public static DateTime StringToTime (string value)
819 return XmlConvert.ToDateTime (value);
823 public static long StringToUnsignedInt (string value)
825 return XmlConvert.ToInt32 (value);
829 public static decimal StringToUnsignedLong (string value)
831 return XmlConvert.ToInt32 (value);
835 public static int StringToUnsignedShort (string value)
837 return XmlConvert.ToInt32 (value);
841 public static TimeSpan StringToYearMonthDuration (string value)
843 return XmlConvert.ToTimeSpan (value);
847 public static string ItemToAnyUri (XPathItem value)
853 public static byte [] ItemToBase64Binary (XPathItem value)
855 return Convert.FromBase64String (value.Value);
859 public static bool ItemToBoolean (XPathItem value)
861 return XmlConvert.ToBoolean (value.Value);
865 public static DateTime ItemToDate (XPathItem value)
867 return XmlConvert.ToDateTime (value.Value);
871 public static DateTime ItemToDateTime (XPathItem value)
873 return XmlConvert.ToDateTime (value.Value);
877 public static TimeSpan ItemToDayTimeDuration (XPathItem value)
879 return XmlConvert.ToTimeSpan (value.Value);
883 public static decimal ItemToDecimal (XPathItem value)
885 return XmlConvert.ToDecimal (value.Value);
889 public static double ItemToDouble (XPathItem value)
891 return XmlConvert.ToDouble (value.Value);
895 public static string ItemToDuration (XPathItem value)
897 return XmlConvert.ToString (XmlConvert.ToTimeSpan (value.Value));
901 public static float ItemToFloat (XPathItem value)
903 return XmlConvert.ToSingle (value.Value);
907 public static DateTime ItemToGDay (XPathItem value)
909 return XmlConvert.ToDateTime (value.Value);
913 public static DateTime ItemToGMonth (XPathItem value)
915 return XmlConvert.ToDateTime (value.Value);
919 public static DateTime ItemToGMonthDay (XPathItem value)
921 return XmlConvert.ToDateTime (value.Value);
925 public static DateTime ItemToGYear (XPathItem value)
927 return XmlConvert.ToDateTime (value.Value);
931 public static DateTime ItemToGYearMonth (XPathItem value)
933 return XmlConvert.ToDateTime (value.Value);
937 public static byte [] ItemToHexBinary (XPathItem value)
939 return XmlConvert.FromBinHexString (value.Value);
943 public static int ItemToInt (XPathItem value)
945 return XmlConvert.ToInt32 (value.Value);
949 public static long ItemToInteger (XPathItem value)
951 return XmlConvert.ToInt64 (value.Value);
955 public static XPathItem ItemToItem (XPathItem value, XmlSchemaType schemaTypeDest)
957 return new XPathAtomicValue (value.Value, schemaTypeDest);
961 public static decimal ItemToNonNegativeInteger (XPathItem value)
963 return XmlConvert.ToDecimal (value.Value);
967 public static decimal ItemToNonPositiveInteger (XPathItem value)
969 return XmlConvert.ToDecimal (value.Value);
973 public static XmlQualifiedName ItemToQName (XPathItem value)
975 return (XmlQualifiedName) value.TypedValue;
979 public static string ItemToString (XPathItem value)
981 if (value.ValueType == typeof (DateTime))
982 return XmlConvert.ToString ((DateTime) value.TypedValue);
983 if (value.TypedValue is XmlQualifiedName)
984 throw new ArgumentException ("Invalid cast from schema QName type to string type.");
989 public static DateTime ItemToTime (XPathItem value)
991 return XmlConvert.ToDateTime (value.Value);
995 public static long ItemToUnsignedInt (XPathItem value)
997 return XmlConvert.ToInt32 (value.Value);
1001 public static decimal ItemToUnsignedLong (XPathItem value)
1003 return XmlConvert.ToInt32 (value.Value);
1007 public static int ItemToUnsignedShort (XPathItem value)
1009 return XmlConvert.ToInt32 (value.Value);
1013 public static TimeSpan ItemToYearMonthDuration (XPathItem value)
1015 return XmlConvert.ToTimeSpan (value.Value);