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
);