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
44 private XQueryConvert ()
48 public static bool ShouldCheckValueFacets (XmlSchemaType schemaTypeDest)
50 XmlSchemaObjectCollection facets = null;
51 XmlSchemaSimpleType st = schemaTypeDest as XmlSchemaSimpleType;
53 XmlSchemaSimpleTypeRestriction r = st.Content
54 as XmlSchemaSimpleTypeRestriction;
59 XmlSchemaComplexType ct =
60 schemaTypeDest as XmlSchemaComplexType;
61 XmlSchemaSimpleContent sc = ct.ContentModel
62 as XmlSchemaSimpleContent;
64 XmlSchemaSimpleContentRestriction r =
65 sc.Content as XmlSchemaSimpleContentRestriction;
70 return facets != null && facets.Count > 0;
73 public static XmlTypeCode GetFallbackType (XmlTypeCode type)
76 case XmlTypeCode.AnyAtomicType:
77 return XmlTypeCode.Item;
78 case XmlTypeCode.UntypedAtomic:
79 return XmlTypeCode.String;
80 case XmlTypeCode.Notation:
81 return XmlTypeCode.QName;
82 case XmlTypeCode.NormalizedString:
83 case XmlTypeCode.Token:
84 case XmlTypeCode.Language:
85 case XmlTypeCode.NmToken:
86 case XmlTypeCode.Name:
87 case XmlTypeCode.NCName:
89 case XmlTypeCode.Idref:
90 case XmlTypeCode.Entity:
91 return XmlTypeCode.String;
92 case XmlTypeCode.NonPositiveInteger:
93 return XmlTypeCode.Decimal;
94 case XmlTypeCode.NegativeInteger:
95 return XmlTypeCode.NonPositiveInteger;
96 case XmlTypeCode.Long:
97 return XmlTypeCode.Integer;
98 case XmlTypeCode.Short:
99 return XmlTypeCode.Int;
100 case XmlTypeCode.Byte:
101 return XmlTypeCode.Int;
102 case XmlTypeCode.NonNegativeInteger:
103 return XmlTypeCode.Decimal;
104 case XmlTypeCode.UnsignedLong:
105 return XmlTypeCode.NonNegativeInteger;
106 case XmlTypeCode.UnsignedInt:
107 return XmlTypeCode.Integer;
108 case XmlTypeCode.UnsignedShort:
109 return XmlTypeCode.Int;
110 case XmlTypeCode.UnsignedByte:
111 return XmlTypeCode.UnsignedShort;
112 case XmlTypeCode.PositiveInteger:
113 return XmlTypeCode.NonNegativeInteger;
115 return XmlTypeCode.None;
120 // See XQuery & XPath 2.0 functions & operators section 17.
121 public static bool CanConvert (XPathItem item, XmlSchemaType schemaTypeDest)
124 throw new ArgumentNullException ("item");
125 if (schemaTypeDest == null)
126 throw new ArgumentNullException ("schemaTypeDest");
127 XmlTypeCode src = item.XmlType.TypeCode;
128 XmlTypeCode dst = schemaTypeDest.TypeCode;
130 // Notation cannot be converted from other than Notation
131 if (src == XmlTypeCode.Notation && dst != XmlTypeCode.Notation)
134 // untypedAtomic and string are convertable unless source type is QName.
136 case XmlTypeCode.UntypedAtomic:
137 case XmlTypeCode.String:
138 return src != XmlTypeCode.QName;
142 case XmlTypeCode.None:
143 case XmlTypeCode.Item:
144 case XmlTypeCode.Node:
145 case XmlTypeCode.Document:
146 case XmlTypeCode.Element:
147 case XmlTypeCode.Attribute:
148 case XmlTypeCode.Namespace:
149 case XmlTypeCode.ProcessingInstruction:
150 case XmlTypeCode.Comment:
151 case XmlTypeCode.Text:
152 throw new NotImplementedException (); // FIXME: check what happens
154 case XmlTypeCode.AnyAtomicType:
155 throw new NotImplementedException (); // FIXME: check what happens
156 case XmlTypeCode.UntypedAtomic:
157 case XmlTypeCode.String:
159 throw new NotImplementedException (); // FIXME: check what happens
161 case XmlTypeCode.Boolean:
162 case XmlTypeCode.Decimal:
164 case XmlTypeCode.Float:
165 case XmlTypeCode.Double:
166 case XmlTypeCode.Decimal:
167 case XmlTypeCode.Boolean:
172 case XmlTypeCode.Float:
173 case XmlTypeCode.Double:
174 if (dst == XmlTypeCode.Decimal)
176 throw new NotImplementedException (); // FIXME: check what happens
177 goto case XmlTypeCode.Decimal;
179 case XmlTypeCode.Duration:
181 case XmlTypeCode.Duration:
182 case XmlTypeCode.YearMonthDuration:
183 case XmlTypeCode.DayTimeDuration:
188 case XmlTypeCode.DateTime:
190 case XmlTypeCode.DateTime:
191 case XmlTypeCode.Time:
192 case XmlTypeCode.Date:
193 case XmlTypeCode.GYearMonth:
194 case XmlTypeCode.GYear:
195 case XmlTypeCode.GMonthDay:
196 case XmlTypeCode.GDay:
197 case XmlTypeCode.GMonth:
202 case XmlTypeCode.Time:
204 case XmlTypeCode.Time:
205 case XmlTypeCode.Date:
210 case XmlTypeCode.Date:
211 if (dst == XmlTypeCode.Time)
213 goto case XmlTypeCode.DateTime;
215 case XmlTypeCode.GYearMonth:
216 case XmlTypeCode.GYear:
217 case XmlTypeCode.GMonthDay:
218 case XmlTypeCode.GDay:
219 case XmlTypeCode.GMonth:
222 case XmlTypeCode.HexBinary:
223 case XmlTypeCode.Base64Binary:
227 case XmlTypeCode.HexBinary:
228 case XmlTypeCode.Base64Binary:
233 case XmlTypeCode.AnyUri:
234 case XmlTypeCode.QName:
235 case XmlTypeCode.Notation:
238 case XmlTypeCode.NormalizedString:
239 case XmlTypeCode.Token:
240 case XmlTypeCode.Language:
241 case XmlTypeCode.NmToken:
242 case XmlTypeCode.Name:
243 case XmlTypeCode.NCName:
245 case XmlTypeCode.Idref:
246 case XmlTypeCode.Entity:
247 case XmlTypeCode.Integer:
248 case XmlTypeCode.NonPositiveInteger:
249 case XmlTypeCode.NegativeInteger:
250 case XmlTypeCode.Long:
251 case XmlTypeCode.Int:
252 case XmlTypeCode.Short:
253 case XmlTypeCode.Byte:
254 case XmlTypeCode.NonNegativeInteger:
255 case XmlTypeCode.UnsignedLong:
256 case XmlTypeCode.UnsignedInt:
257 case XmlTypeCode.UnsignedShort:
258 case XmlTypeCode.UnsignedByte:
259 case XmlTypeCode.PositiveInteger:
260 throw new NotImplementedException ();
263 case XmlTypeCode.YearMonthDuration:
264 if (dst == XmlTypeCode.DayTimeDuration)
266 goto case XmlTypeCode.Duration;
267 case XmlTypeCode.DayTimeDuration:
268 if (dst == XmlTypeCode.YearMonthDuration)
270 goto case XmlTypeCode.Duration;
273 throw new NotImplementedException ();
276 // Individual conversion
278 public static string AnyUriToString (string value)
283 public static byte [] Base64BinaryToHexBinary (byte [] value)
285 return XmlConvert.FromBinHexString (Convert.ToBase64String (value));
288 public static string Base64BinaryToString (byte [] value)
290 return Convert.ToBase64String (value);
293 public static decimal BooleanToDecimal (bool value)
295 return Convert.ToDecimal (value);
298 public static double BooleanToDouble (bool value)
300 return Convert.ToDouble (value);
303 public static float BooleanToFloat (bool value)
305 return Convert.ToSingle (value);
308 public static int BooleanToInt (bool value)
310 return Convert.ToInt32 (value);
313 public static long BooleanToInteger (bool value)
315 return Convert.ToInt64 (value);
318 public static string BooleanToString (bool value)
320 // It looks not returning "True"
321 return value ? "true" : "false";
324 public static DateTime DateTimeToDate (DateTime value)
329 public static DateTime DateTimeToGDay (DateTime value)
331 return new DateTime (0, 0, value.Day);
334 public static DateTime DateTimeToGMonth (DateTime value)
336 return new DateTime (0, value.Month, 0);
339 public static DateTime DateTimeToGMonthDay (DateTime value)
341 return new DateTime (0, value.Month, value.Day);
344 public static DateTime DateTimeToGYear (DateTime value)
346 return new DateTime (value.Year, 0, 0);
349 public static DateTime DateTimeToGYearMonth (DateTime value)
351 return new DateTime (value.Year, value.Month, 0);
354 public static DateTime DateTimeToTime (DateTime value)
356 return new DateTime (value.TimeOfDay.Ticks);
359 public static DateTime DateToDateTime (DateTime value)
364 public static DateTime DateToGDay (DateTime value)
366 return new DateTime (0, 0, value.Day);
369 public static DateTime DateToGMonth (DateTime value)
371 return new DateTime (0, value.Month, 0);
374 public static DateTime DateToGMonthDay (DateTime value)
376 return new DateTime (0, value.Month, value.Day);
379 public static DateTime DateToGYear (DateTime value)
381 return new DateTime (value.Year, 0, 0);
384 public static DateTime DateToGYearMonth (DateTime value)
386 return new DateTime (value.Year, value.Month, 0);
389 public static string DateToString (DateTime value)
391 return XmlConvert.ToString (value);
394 public static string DateTimeToString (DateTime value)
396 return XmlConvert.ToString (value);
399 public static string DayTimeDurationToDuration (TimeSpan value)
401 return XmlConvert.ToString (value);
404 public static string DayTimeDurationToString (TimeSpan value)
406 return DayTimeDurationToDuration (value);
409 public static bool DecimalToBoolean (decimal value)
414 public static double DecimalToDouble (decimal value)
416 return Convert.ToDouble (value);
419 public static float DecimalToFloat (decimal value)
421 return Convert.ToSingle (value);
424 public static int DecimalToInt (decimal value)
426 return Convert.ToInt32 (value);
429 public static long DecimalToInteger (decimal value)
431 return Convert.ToInt64 (value);
434 [MonoTODO] // what if value was negative?
435 public static decimal DecimalToNonNegativeInteger (decimal value)
437 // MS has a bug that does not reject negative values.
438 throw new NotImplementedException ();
441 [MonoTODO] // what if value was positive?
442 public static decimal DecimalToNonPositiveInteger (decimal value)
444 throw new NotImplementedException ();
447 public static string DecimalToString (decimal value)
449 return XmlConvert.ToString (value);
452 public static bool DoubleToBoolean (double value)
457 public static decimal DoubleToDecimal (double value)
459 return (decimal) value;
462 public static float DoubleToFloat (double value)
464 return Convert.ToSingle (value);
467 public static int DoubleToInt (double value)
469 return Convert.ToInt32 (value);
472 public static long DoubleToInteger (double value)
474 return Convert.ToInt64 (value);
477 [MonoTODO] // what if value was negative?
478 public static decimal DoubleToNonNegativeInteger (double value)
480 // MS has a bug that does not reject negative values.
481 throw new NotImplementedException ();
484 [MonoTODO] // what if value was positive?
485 public static decimal DoubleToNonPositiveInteger (double value)
487 throw new NotImplementedException ();
490 public static string DoubleToString (double value)
492 return XmlConvert.ToString (value);
495 public static TimeSpan DurationToDayTimeDuration (string value)
497 return XmlConvert.ToTimeSpan (value);
500 public static string DurationToString (string value)
502 return XmlConvert.ToString (XmlConvert.ToTimeSpan (value));
505 public static TimeSpan DurationToYearMonthDuration (string value)
507 return XmlConvert.ToTimeSpan (value);
511 public static bool FloatToBoolean (float value)
516 public static decimal FloatToDecimal (float value)
518 return (decimal) value;
521 public static double FloatToDouble (float value)
523 return Convert.ToDouble (value);
526 public static int FloatToInt (float value)
528 return Convert.ToInt32 (value);
531 public static long FloatToInteger (float value)
533 return Convert.ToInt64 (value);
536 [MonoTODO] // what if value was negative?
537 public static decimal FloatToNonNegativeInteger (float value)
539 // MS has a bug that does not reject negative values.
540 throw new NotImplementedException ();
543 [MonoTODO] // what if value was positive?
544 public static decimal FloatToNonPositiveInteger (float value)
546 throw new NotImplementedException ();
549 public static string FloatToString (float value)
551 return XmlConvert.ToString (value);
554 public static string GDayToString (DateTime value)
556 return XmlConvert.ToString (TimeSpan.FromDays (value.Day));
559 public static string GMonthDayToString (DateTime value)
561 return XmlConvert.ToString (new TimeSpan (value.Day, value.Hour, value.Minute, value.Second));
564 public static string GMonthToString (DateTime value)
566 return XmlConvert.ToString (new TimeSpan (0, value.Month, 0));
569 public static string GYearMonthToString (DateTime value)
571 return XmlConvert.ToString (new TimeSpan (value.Year, value.Month, 0));
574 public static string GYearToString (DateTime value)
576 return XmlConvert.ToString (new TimeSpan (new DateTime (value.Year, 0, 0).Ticks));
579 public static string HexBinaryToString (byte [] data)
581 return XmlConvert.ToBinHexString (data);
584 public static byte [] HexBinaryToBase64Binary (byte [] data)
586 return data;//XmlConvert.ToBinHexString (data);
590 public static bool IntegerToBoolean (long value)
595 public static decimal IntegerToDecimal (long value)
597 return (decimal) value;
600 public static double IntegerToDouble (long value)
602 return Convert.ToDouble (value);
605 public static float IntegerToFloat (long value)
607 return Convert.ToSingle (value);
610 public static int IntegerToInt (long value)
612 return Convert.ToInt32 (value);
615 public static string IntegerToString (long value)
617 return XmlConvert.ToString (value);
620 public static bool IntToBoolean (int value)
625 public static decimal IntToDecimal (int value)
627 return (decimal) value;
630 public static double IntToDouble (int value)
632 return Convert.ToDouble (value);
635 public static float IntToFloat (int value)
637 return Convert.ToSingle (value);
640 public static long IntToInteger (int value)
645 public static string IntToString (int value)
647 return XmlConvert.ToString (value);
650 public static string NonNegativeIntegerToString (decimal value)
652 return XmlConvert.ToString (value);
655 public static string NonPositiveIntegerToString (decimal value)
657 return XmlConvert.ToString (value);
660 public static DateTime TimeToDateTime (DateTime value)
665 public static string TimeToString (DateTime value)
667 return XmlConvert.ToString (value, "HH:mm:ssZ");
670 public static string YearMonthDurationToDuration (TimeSpan value)
672 return XmlConvert.ToString (value);
675 public static string YearMonthDurationToString (TimeSpan value)
677 return YearMonthDurationToDuration (value);
680 public static string StringToAnyUri (string value)
685 public static byte [] StringToBase64Binary (string value)
687 return Convert.FromBase64String (value);
690 public static bool StringToBoolean (string value)
692 return XmlConvert.ToBoolean (value);
695 public static DateTime StringToDate (string value)
697 return XmlConvert.ToDateTime (value);
700 public static DateTime StringToDateTime (string value)
702 return XmlConvert.ToDateTime (value);
705 public static TimeSpan StringToDayTimeDuration (string value)
707 return XmlConvert.ToTimeSpan (value);
710 public static decimal StringToDecimal (string value)
712 return XmlConvert.ToDecimal (value);
715 public static double StringToDouble (string value)
717 return XmlConvert.ToDouble (value);
720 public static string StringToDuration (string value)
722 return XmlConvert.ToString (XmlConvert.ToTimeSpan (value));
725 public static float StringToFloat (string value)
727 return XmlConvert.ToSingle (value);
730 public static DateTime StringToGDay (string value)
732 return XmlConvert.ToDateTime (value);
735 public static DateTime StringToGMonth (string value)
737 return XmlConvert.ToDateTime (value);
740 public static DateTime StringToGMonthDay (string value)
742 return XmlConvert.ToDateTime (value);
745 public static DateTime StringToGYear (string value)
747 return XmlConvert.ToDateTime (value);
750 public static DateTime StringToGYearMonth (string value)
752 return XmlConvert.ToDateTime (value);
755 public static byte [] StringToHexBinary (string value)
757 return XmlConvert.FromBinHexString (value);
760 public static int StringToInt (string value)
762 return XmlConvert.ToInt32 (value);
765 public static long StringToInteger (string value)
767 return XmlConvert.ToInt64 (value);
770 public static decimal StringToNonNegativeInteger (string value)
772 return XmlConvert.ToDecimal (value);
775 public static decimal StringToNonPositiveInteger (string value)
777 return XmlConvert.ToDecimal (value);
780 public static DateTime StringToTime (string value)
782 return XmlConvert.ToDateTime (value);
785 public static long StringToUnsignedInt (string value)
787 return XmlConvert.ToUInt32 (value);
790 public static decimal StringToUnsignedLong (string value)
792 return XmlConvert.ToUInt64 (value);
795 public static int StringToUnsignedShort (string value)
797 return XmlConvert.ToUInt16 (value);
800 public static TimeSpan StringToYearMonthDuration (string value)
802 return XmlConvert.ToTimeSpan (value);
805 public static string ItemToAnyUri (XPathItem value)
810 public static byte [] ItemToBase64Binary (XPathItem value)
812 return Convert.FromBase64String (value.Value);
815 public static bool ItemToBoolean (XPathItem value)
817 return XmlConvert.ToBoolean (value.Value);
820 public static DateTime ItemToDate (XPathItem value)
822 return XmlConvert.ToDateTime (value.Value);
825 public static DateTime ItemToDateTime (XPathItem value)
827 return XmlConvert.ToDateTime (value.Value);
830 public static TimeSpan ItemToDayTimeDuration (XPathItem value)
832 return XmlConvert.ToTimeSpan (value.Value);
835 public static decimal ItemToDecimal (XPathItem value)
837 return XmlConvert.ToDecimal (value.Value);
840 public static double ItemToDouble (XPathItem value)
842 return XmlConvert.ToDouble (value.Value);
845 public static string ItemToDuration (XPathItem value)
847 return XmlConvert.ToString (XmlConvert.ToTimeSpan (value.Value));
850 public static float ItemToFloat (XPathItem value)
852 return XmlConvert.ToSingle (value.Value);
855 public static DateTime ItemToGDay (XPathItem value)
857 return XmlConvert.ToDateTime (value.Value);
860 public static DateTime ItemToGMonth (XPathItem value)
862 return XmlConvert.ToDateTime (value.Value);
865 public static DateTime ItemToGMonthDay (XPathItem value)
867 return XmlConvert.ToDateTime (value.Value);
870 public static DateTime ItemToGYear (XPathItem value)
872 return XmlConvert.ToDateTime (value.Value);
875 public static DateTime ItemToGYearMonth (XPathItem value)
877 return XmlConvert.ToDateTime (value.Value);
880 public static byte [] ItemToHexBinary (XPathItem value)
882 return XmlConvert.FromBinHexString (value.Value);
885 public static int ItemToInt (XPathItem value)
887 return XmlConvert.ToInt32 (value.Value);
890 public static long ItemToInteger (XPathItem value)
892 return XmlConvert.ToInt64 (value.Value);
895 public static XPathItem ItemToItem (XPathItem value, XmlSchemaType schemaTypeDest)
897 return new XmlAtomicValue (value.Value, schemaTypeDest);
900 public static decimal ItemToNonNegativeInteger (XPathItem value)
902 return XmlConvert.ToDecimal (value.Value);
905 public static decimal ItemToNonPositiveInteger (XPathItem value)
907 return XmlConvert.ToDecimal (value.Value);
910 public static XmlQualifiedName ItemToQName (XPathItem value)
912 return (XmlQualifiedName) value.TypedValue;
915 public static string ItemToString (XPathItem value)
917 if (value.ValueType == typeof (DateTime))
918 return XmlConvert.ToString ((DateTime) value.TypedValue);
919 if (value.TypedValue is XmlQualifiedName)
920 throw new ArgumentException ("Invalid cast from schema QName type to string type.");
924 public static DateTime ItemToTime (XPathItem value)
926 return XmlConvert.ToDateTime (value.Value);
930 public static long ItemToUnsignedInt (XPathItem value)
933 return XmlConvert.ToInt32 (value.Value);
937 public static decimal ItemToUnsignedLong (XPathItem value)
940 return XmlConvert.ToInt32 (value.Value);
944 public static int ItemToUnsignedShort (XPathItem value)
947 return XmlConvert.ToInt32 (value.Value);
950 public static TimeSpan ItemToYearMonthDuration (XPathItem value)
952 return XmlConvert.ToTimeSpan (value.Value);