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.
33 using System.Globalization;
37 using System.Xml.Schema;
38 using System.Xml.XPath;
42 internal class XQueryConvert // Won't be public in the final stage
45 public static bool ShouldCheckValueFacets (XmlSchemaType schemaTypeDest)
47 throw new NotImplementedException ();
50 public static XmlTypeCode GetFallbackType (XmlTypeCode type)
53 case XmlTypeCode.AnyAtomicType:
54 return XmlTypeCode.Item;
55 case XmlTypeCode.UntypedAtomic:
56 return XmlTypeCode.String;
57 case XmlTypeCode.Notation:
58 return XmlTypeCode.QName;
59 case XmlTypeCode.NormalizedString:
60 case XmlTypeCode.Token:
61 case XmlTypeCode.Language:
62 case XmlTypeCode.NmToken:
63 case XmlTypeCode.Name:
64 case XmlTypeCode.NCName:
66 case XmlTypeCode.Idref:
67 case XmlTypeCode.Entity:
68 return XmlTypeCode.String;
69 case XmlTypeCode.NonPositiveInteger:
70 return XmlTypeCode.Decimal;
71 case XmlTypeCode.NegativeInteger:
72 return XmlTypeCode.NonPositiveInteger;
73 case XmlTypeCode.Long:
74 return XmlTypeCode.Integer;
75 case XmlTypeCode.Short:
76 return XmlTypeCode.Int;
77 case XmlTypeCode.Byte:
78 return XmlTypeCode.Int;
79 case XmlTypeCode.NonNegativeInteger:
80 return XmlTypeCode.Decimal;
81 case XmlTypeCode.UnsignedLong:
82 return XmlTypeCode.NonNegativeInteger;
83 case XmlTypeCode.UnsignedInt:
84 return XmlTypeCode.Integer;
85 case XmlTypeCode.UnsignedShort:
86 return XmlTypeCode.Int;
87 case XmlTypeCode.UnsignedByte:
88 return XmlTypeCode.UnsignedShort;
89 case XmlTypeCode.PositiveInteger:
90 return XmlTypeCode.NonNegativeInteger;
92 return XmlTypeCode.None;
97 // See XQuery & XPath 2.0 functions & operators section 17.
98 public static bool CanConvert (XPathItem item, XmlSchemaType schemaTypeDest)
101 throw new ArgumentNullException ("item");
102 if (schemaTypeDest == null)
103 throw new ArgumentNullException ("schemaTypeDest");
104 XmlTypeCode src = item.XmlType.TypeCode;
105 XmlTypeCode dst = schemaTypeDest.TypeCode;
107 // Notation cannot be converted from other than Notation
108 if (src == XmlTypeCode.Notation && dst != XmlTypeCode.Notation)
111 // untypedAtomic and string are convertable unless source type is QName.
113 case XmlTypeCode.UntypedAtomic:
114 case XmlTypeCode.String:
115 return src != XmlTypeCode.QName;
119 case XmlTypeCode.None:
120 case XmlTypeCode.Item:
121 case XmlTypeCode.Node:
122 case XmlTypeCode.Document:
123 case XmlTypeCode.Element:
124 case XmlTypeCode.Attribute:
125 case XmlTypeCode.Namespace:
126 case XmlTypeCode.ProcessingInstruction:
127 case XmlTypeCode.Comment:
128 case XmlTypeCode.Text:
129 throw new NotImplementedException (); // FIXME: check what happens
131 case XmlTypeCode.AnyAtomicType:
132 throw new NotImplementedException (); // FIXME: check what happens
133 case XmlTypeCode.UntypedAtomic:
134 case XmlTypeCode.String:
136 throw new NotImplementedException (); // FIXME: check what happens
138 case XmlTypeCode.Boolean:
139 case XmlTypeCode.Decimal:
141 case XmlTypeCode.Float:
142 case XmlTypeCode.Double:
143 case XmlTypeCode.Decimal:
144 case XmlTypeCode.Boolean:
149 case XmlTypeCode.Float:
150 case XmlTypeCode.Double:
151 if (dst == XmlTypeCode.Decimal)
153 throw new NotImplementedException (); // FIXME: check what happens
154 goto case XmlTypeCode.Decimal;
156 case XmlTypeCode.Duration:
158 case XmlTypeCode.Duration:
159 case XmlTypeCode.YearMonthDuration:
160 case XmlTypeCode.DayTimeDuration:
165 case XmlTypeCode.DateTime:
167 case XmlTypeCode.DateTime:
168 case XmlTypeCode.Time:
169 case XmlTypeCode.Date:
170 case XmlTypeCode.GYearMonth:
171 case XmlTypeCode.GYear:
172 case XmlTypeCode.GMonthDay:
173 case XmlTypeCode.GDay:
174 case XmlTypeCode.GMonth:
179 case XmlTypeCode.Time:
181 case XmlTypeCode.Time:
182 case XmlTypeCode.Date:
187 case XmlTypeCode.Date:
188 if (dst == XmlTypeCode.Time)
190 goto case XmlTypeCode.DateTime;
192 case XmlTypeCode.GYearMonth:
193 case XmlTypeCode.GYear:
194 case XmlTypeCode.GMonthDay:
195 case XmlTypeCode.GDay:
196 case XmlTypeCode.GMonth:
199 case XmlTypeCode.HexBinary:
200 case XmlTypeCode.Base64Binary:
204 case XmlTypeCode.HexBinary:
205 case XmlTypeCode.Base64Binary:
210 case XmlTypeCode.AnyUri:
211 case XmlTypeCode.QName:
212 case XmlTypeCode.Notation:
215 case XmlTypeCode.NormalizedString:
216 case XmlTypeCode.Token:
217 case XmlTypeCode.Language:
218 case XmlTypeCode.NmToken:
219 case XmlTypeCode.Name:
220 case XmlTypeCode.NCName:
222 case XmlTypeCode.Idref:
223 case XmlTypeCode.Entity:
224 case XmlTypeCode.Integer:
225 case XmlTypeCode.NonPositiveInteger:
226 case XmlTypeCode.NegativeInteger:
227 case XmlTypeCode.Long:
228 case XmlTypeCode.Int:
229 case XmlTypeCode.Short:
230 case XmlTypeCode.Byte:
231 case XmlTypeCode.NonNegativeInteger:
232 case XmlTypeCode.UnsignedLong:
233 case XmlTypeCode.UnsignedInt:
234 case XmlTypeCode.UnsignedShort:
235 case XmlTypeCode.UnsignedByte:
236 case XmlTypeCode.PositiveInteger:
237 throw new NotImplementedException ();
240 case XmlTypeCode.YearMonthDuration:
241 if (dst == XmlTypeCode.DayTimeDuration)
243 goto case XmlTypeCode.Duration;
244 case XmlTypeCode.DayTimeDuration:
245 if (dst == XmlTypeCode.YearMonthDuration)
247 goto case XmlTypeCode.Duration;
250 throw new NotImplementedException ();
253 // Individual conversion
255 public static string AnyUriToString (string value)
260 public static byte [] Base64BinaryToHexBinary (byte [] value)
262 return XmlConvert.FromBinHexString (Convert.ToBase64String (value));
265 public static string Base64BinaryToString (byte [] value)
267 return Convert.ToBase64String (value);
270 public static decimal BooleanToDecimal (bool value)
272 return Convert.ToDecimal (value);
275 public static double BooleanToDouble (bool value)
277 return Convert.ToDouble (value);
280 public static float BooleanToFloat (bool value)
282 return Convert.ToSingle (value);
285 public static int BooleanToInt (bool value)
287 return Convert.ToInt32 (value);
290 public static long BooleanToInteger (bool value)
292 return Convert.ToInt64 (value);
295 public static string BooleanToString (bool value)
297 // It looks not returning "True"
298 return value ? "true" : "false";
302 public static DateTime DateTimeToDate (DateTime value)
308 public static DateTime DateTimeToGDay (DateTime value)
310 return new DateTime (0, 0, value.Day);
314 public static DateTime DateTimeToGMonth (DateTime value)
316 return new DateTime (0, value.Month, 0);
320 public static DateTime DateTimeToGYear (DateTime value)
322 return new DateTime (value.Year, 0, 0);
326 public static DateTime DateTimeToGYearMonth (DateTime value)
328 return new DateTime (value.Year, value.Month, 0);
332 public static DateTime DateToDateTime (DateTime value)
338 public static DateTime DateToGDay (DateTime value)
340 return new DateTime (0, 0, value.Day);
344 public static DateTime DateToGMonth (DateTime value)
346 return new DateTime (0, value.Month, 0);
350 public static DateTime DateToGYear (DateTime value)
352 return new DateTime (value.Year, 0, 0);
356 public static DateTime DateToGYearMonth (DateTime value)
358 return new DateTime (value.Year, value.Month, 0);
362 public static string DateToString (DateTime value)
364 return XmlConvert.ToString (value);
368 public static string DateTimeToString (DateTime value)
370 return XmlConvert.ToString (value);
374 public static string DayTimeDurationToDuration (TimeSpan value)
376 return XmlConvert.ToString (value);
380 public static string DayTimeDurationToString (TimeSpan value)
382 return DayTimeDurationToDuration (value);
386 public static bool DecimalToBoolean (decimal value)
392 public static double DecimalToDouble (decimal value)
394 return (double) value;
398 public static float DecimalToFloat (decimal value)
400 return (float) value;
404 public static int DecimalToInt (decimal value)
410 public static long DecimalToInteger (decimal value)
415 [MonoTODO] // what if value was negative?
416 public static decimal DecimalToNonNegativeInteger (decimal value)
418 throw new NotImplementedException ();
421 [MonoTODO] // what if value was positive?
422 public static decimal DecimalToNonPositiveInteger (decimal value)
424 throw new NotImplementedException ();
428 public static string DecimalToString (decimal value)
430 return XmlConvert.ToString (value);
434 public static bool DoubleToBoolean (double value)
440 public static decimal DoubleToDecimal (double value)
442 return (decimal) value;
446 public static float DoubleToFloat (double value)
448 return (float) value;
452 public static int DoubleToInt (double value)
458 public static long DoubleToInteger (double value)
463 [MonoTODO] // what if value was negative?
464 public static decimal DoubleToNonNegativeInteger (double value)
466 throw new NotImplementedException ();
469 [MonoTODO] // what if value was positive?
470 public static decimal DoubleToNonPositiveInteger (double value)
472 throw new NotImplementedException ();
476 public static string DoubleToString (double value)
478 return XmlConvert.ToString (value);
482 public static TimeSpan DurationToDayTimeDuration (string value)
484 return XmlConvert.ToTimeSpan (value);
488 public static string DurationToString (string value)
490 return XmlConvert.ToString (XmlConvert.ToTimeSpan (value));
494 public static TimeSpan DurationToYearMonthDuration (string value)
496 return XmlConvert.ToTimeSpan (value);
501 public static bool FloatToBoolean (float value)
507 public static decimal FloatToDecimal (float value)
509 return (decimal) value;
513 public static double FloatToDouble (float value)
515 return (double) value;
519 public static int FloatToInt (float value)
525 public static long FloatToInteger (float value)
530 [MonoTODO] // what if value was negative?
531 public static decimal FloatToNonNegativeInteger (float value)
533 throw new NotImplementedException ();
536 [MonoTODO] // what if value was positive?
537 public static decimal FloatToNonPositiveInteger (float value)
539 throw new NotImplementedException ();
543 public static string FloatToString (float value)
545 return XmlConvert.ToString (value);
549 public static string GDayToString (DateTime value)
551 return XmlConvert.ToString (TimeSpan.FromDays (value.Day));
555 public static string GMonthDayToString (DateTime value)
557 return XmlConvert.ToString (new TimeSpan (value.Day, value.Hour, value.Minute, value.Second));
561 public static string GMonthToString (DateTime value)
563 return XmlConvert.ToString (new TimeSpan (0, value.Month, 0));
567 public static string GYearMonthToString (DateTime value)
569 return XmlConvert.ToString (new TimeSpan (value.Year, value.Month, 0));
573 public static string GYearToString (DateTime value)
575 return XmlConvert.ToString (new TimeSpan (new DateTime (value.Year, 0, 0).Ticks));
578 public static string HexBinaryToString (byte [] data)
580 return XmlConvert.ToBinHexString (data);
583 public static string HexBinaryToBase64String (byte [] data)
585 return XmlConvert.ToBinHexString (data);
590 public static bool IntegerToBoolean (long value)
596 public static decimal IntegerToDecimal (long value)
598 return (decimal) value;
602 public static double IntegerToDouble (long value)
604 return (double) value;
608 public static float IntegerToFloat (long value)
610 return (float) value;
614 public static int IntegerToInt (long value)
620 public static string IntegerToString (long value)
622 return XmlConvert.ToString (value);
626 public static bool IntToBoolean (int value)
632 public static decimal IntToDecimal (int value)
634 return (decimal) value;
638 public static double IntToDouble (int value)
640 return (double) value;
644 public static float IntToFloat (int value)
646 return (float) value;
650 public static long IntToInteger (int value)
656 public static string IntToString (int value)
658 return XmlConvert.ToString (value);
662 public static string NonNegativeIntegerToString (decimal value)
664 return XmlConvert.ToString (value);
668 public static string NonPositiveIntegerToString (decimal value)
670 return XmlConvert.ToString (value);
674 public static DateTime TimeToDateTime (DateTime value)
680 public static string TimeToString (DateTime value)
682 return XmlConvert.ToString (value, "HH:mm:ssZ");
686 public static string YearMonthDurationToDuration (TimeSpan value)
688 return XmlConvert.ToString (value);
692 public static string YearMonthDurationToString (TimeSpan value)
694 return YearMonthDurationToDuration (value);
698 public static string StringToAnyUri (string value)
704 public static byte [] StringToBase64Binary (string value)
706 return Convert.FromBase64String (value);
710 public static bool StringToBoolean (string value)
712 return XmlConvert.ToBoolean (value);
716 public static DateTime StringToDate (string value)
718 return XmlConvert.ToDateTime (value);
722 public static DateTime StringToDateTime (string value)
724 return XmlConvert.ToDateTime (value);
728 public static TimeSpan StringToDayTimeDuration (string value)
730 return XmlConvert.ToTimeSpan (value);
734 public static decimal StringToDecimal (string value)
736 return XmlConvert.ToDecimal (value);
740 public static double StringToDouble (string value)
742 return XmlConvert.ToDouble (value);
746 public static string StringToDuration (string value)
748 return XmlConvert.ToString (XmlConvert.ToTimeSpan (value));
752 public static float StringToFloat (string value)
754 return XmlConvert.ToSingle (value);
758 public static DateTime StringToGDay (string value)
760 return XmlConvert.ToDateTime (value);
764 public static DateTime StringToGMonth (string value)
766 return XmlConvert.ToDateTime (value);
770 public static DateTime StringToGMonthDay (string value)
772 return XmlConvert.ToDateTime (value);
776 public static DateTime StringToGYear (string value)
778 return XmlConvert.ToDateTime (value);
782 public static DateTime StringToGYearMonth (string value)
784 return XmlConvert.ToDateTime (value);
788 public static byte [] StringToHexBinary (string value)
790 return XmlConvert.FromBinHexString (value);
794 public static int StringToInt (string value)
796 return XmlConvert.ToInt32 (value);
800 public static long StringToInteger (string value)
802 return XmlConvert.ToInt64 (value);
806 public static decimal StringToNonNegativeInteger (string value)
808 return XmlConvert.ToDecimal (value);
812 public static decimal StringToNonPositiveInteger (string value)
814 return XmlConvert.ToDecimal (value);
818 public static DateTime StringToTime (string value)
820 return XmlConvert.ToDateTime (value);
824 public static long StringToUnsignedInt (string value)
826 return XmlConvert.ToInt32 (value);
830 public static decimal StringToUnsignedLong (string value)
832 return XmlConvert.ToInt32 (value);
836 public static int StringToUnsignedShort (string value)
838 return XmlConvert.ToInt32 (value);
842 public static TimeSpan StringToYearMonthDuration (string value)
844 return XmlConvert.ToTimeSpan (value);
848 public static string ItemToAnyUri (XPathItem value)
854 public static byte [] ItemToBase64Binary (XPathItem value)
856 return Convert.FromBase64String (value.Value);
860 public static bool ItemToBoolean (XPathItem value)
862 return XmlConvert.ToBoolean (value.Value);
866 public static DateTime ItemToDate (XPathItem value)
868 return XmlConvert.ToDateTime (value.Value);
872 public static DateTime ItemToDateTime (XPathItem value)
874 return XmlConvert.ToDateTime (value.Value);
878 public static TimeSpan ItemToDayTimeDuration (XPathItem value)
880 return XmlConvert.ToTimeSpan (value.Value);
884 public static decimal ItemToDecimal (XPathItem value)
886 return XmlConvert.ToDecimal (value.Value);
890 public static double ItemToDouble (XPathItem value)
892 return XmlConvert.ToDouble (value.Value);
896 public static string ItemToDuration (XPathItem value)
898 return XmlConvert.ToString (XmlConvert.ToTimeSpan (value.Value));
902 public static float ItemToFloat (XPathItem value)
904 return XmlConvert.ToSingle (value.Value);
908 public static DateTime ItemToGDay (XPathItem value)
910 return XmlConvert.ToDateTime (value.Value);
914 public static DateTime ItemToGMonth (XPathItem value)
916 return XmlConvert.ToDateTime (value.Value);
920 public static DateTime ItemToGMonthDay (XPathItem value)
922 return XmlConvert.ToDateTime (value.Value);
926 public static DateTime ItemToGYear (XPathItem value)
928 return XmlConvert.ToDateTime (value.Value);
932 public static DateTime ItemToGYearMonth (XPathItem value)
934 return XmlConvert.ToDateTime (value.Value);
938 public static byte [] ItemToHexBinary (XPathItem value)
940 return XmlConvert.FromBinHexString (value.Value);
944 public static int ItemToInt (XPathItem value)
946 return XmlConvert.ToInt32 (value.Value);
950 public static long ItemToInteger (XPathItem value)
952 return XmlConvert.ToInt64 (value.Value);
956 public static XPathItem ItemToItem (XPathItem value, XmlSchemaType schemaTypeDest)
958 return new XPathAtomicValue (value.Value, schemaTypeDest);
962 public static decimal ItemToNonNegativeInteger (XPathItem value)
964 return XmlConvert.ToDecimal (value.Value);
968 public static decimal ItemToNonPositiveInteger (XPathItem value)
970 return XmlConvert.ToDecimal (value.Value);
974 public static XmlQualifiedName ItemToQName (XPathItem value)
976 return (XmlQualifiedName) value.TypedValue;
980 public static string ItemToString (XPathItem value)
982 if (value.ValueType == typeof (DateTime))
983 return XmlConvert.ToString ((DateTime) value.TypedValue);
984 if (value.TypedValue is XmlQualifiedName)
985 throw new ArgumentException ("Invalid cast from schema QName type to string type.");
990 public static DateTime ItemToTime (XPathItem value)
992 return XmlConvert.ToDateTime (value.Value);
996 public static long ItemToUnsignedInt (XPathItem value)
998 return XmlConvert.ToInt32 (value.Value);
1002 public static decimal ItemToUnsignedLong (XPathItem value)
1004 return XmlConvert.ToInt32 (value.Value);
1008 public static int ItemToUnsignedShort (XPathItem value)
1010 return XmlConvert.ToInt32 (value.Value);
1014 public static TimeSpan ItemToYearMonthDuration (XPathItem value)
1016 return XmlConvert.ToTimeSpan (value.Value);