XmlConvert.cs 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439
  1. //
  2. // System.Xml.XmlConvert
  3. //
  4. // Authors:
  5. // Dwivedi, Ajay kumar ([email protected])
  6. // Gonzalo Paniagua Javier ([email protected])
  7. // Alan Tam Siu Lung ([email protected])
  8. //
  9. // (C) 2002 Ximian, Inc (http://www.ximian.com)
  10. //
  11. using System;
  12. using System.Text;
  13. using System.Globalization;
  14. namespace System.Xml {
  15. public class XmlConvert {
  16. static string encodedColon = "_x003A_";
  17. public XmlConvert()
  18. {}
  19. private static string TryDecoding (string s)
  20. {
  21. if (s == null || s.Length < 6)
  22. return s;
  23. char c = '\uFFFF';
  24. try {
  25. c = (char) Int32.Parse (s.Substring (1, 4), NumberStyles.HexNumber);
  26. } catch {
  27. return s [0] + DecodeName (s.Substring (1));
  28. }
  29. if (s.Length == 6)
  30. return c.ToString ();
  31. return c + DecodeName (s.Substring (6));
  32. }
  33. public static string DecodeName (string name)
  34. {
  35. if (name == null || name.Length == 0)
  36. return name;
  37. int pos = name.IndexOf ('_');
  38. if (pos == -1 || pos + 6 >= name.Length)
  39. return name;
  40. if (Char.ToUpper (name [pos + 1]) != 'X' || name [pos + 6] != '_')
  41. return name [0] + DecodeName (name.Substring (1));
  42. return name.Substring (0, pos) + TryDecoding (name.Substring (pos + 1));
  43. }
  44. public static string EncodeLocalName (string name)
  45. {
  46. string encoded = EncodeName (name);
  47. int pos = encoded.IndexOf (':');
  48. if (pos == -1)
  49. return encoded;
  50. return encoded.Replace (":", encodedColon);
  51. }
  52. internal static bool IsInvalid (char c, bool firstOnlyLetter)
  53. {
  54. if (c == ':') // Special case. allowed in EncodeName, but encoded in EncodeLocalName
  55. return false;
  56. if (firstOnlyLetter && !Char.IsLetter (c) && c != '_')
  57. return false;
  58. return !Char.IsLetterOrDigit (c);
  59. }
  60. private static string EncodeName (string name, bool nmtoken)
  61. {
  62. StringBuilder sb = new StringBuilder ();
  63. int length = name.Length;
  64. for (int i = 0; i < length; i++) {
  65. char c = name [i];
  66. if (c != '_' || i + 6 >= length) {
  67. bool firstOnlyLetter = (i == 0 && !nmtoken);
  68. if (IsInvalid (c, firstOnlyLetter)) {
  69. sb.AppendFormat ("_x{0:X4}_", (int) c);
  70. continue;
  71. }
  72. } else {
  73. if (Char.ToUpper (name [i + 1]) == 'X' && name [i + 6] == '_') {
  74. string decoded = TryDecoding (name.Substring (i + 1, 6));
  75. if (decoded.Length == 1) {
  76. sb.AppendFormat ("_x{0:X4}_", (int) c);
  77. continue;
  78. }
  79. }
  80. }
  81. sb.Append (c);
  82. }
  83. return sb.ToString ();
  84. }
  85. public static string EncodeName (string name)
  86. {
  87. return EncodeName (name, false);
  88. }
  89. public static string EncodeNmToken(string name)
  90. {
  91. return EncodeName (name, true);
  92. }
  93. // {true, false, 1, 0}
  94. public static bool ToBoolean(string s)
  95. {
  96. s = s.Trim();
  97. switch(s)
  98. {
  99. case "1":
  100. return true;
  101. case "true":
  102. return true;
  103. case "0":
  104. return false;
  105. case "false":
  106. return false;
  107. default:
  108. throw new FormatException(s + " is not a valid boolean value");
  109. }
  110. }
  111. public static byte ToByte(string s)
  112. {
  113. return Byte.Parse(s, CultureInfo.InvariantCulture);
  114. }
  115. public static char ToChar(string s)
  116. {
  117. return Char.Parse(s);
  118. }
  119. public static DateTime ToDateTime(string s)
  120. {
  121. return ToDateTime(s, new string[] {
  122. // dateTime
  123. "yyyy-MM-ddTHH:mm:ss",
  124. "yyyy-MM-ddTHH:mm:ss.f",
  125. "yyyy-MM-ddTHH:mm:ss.ff",
  126. "yyyy-MM-ddTHH:mm:ss.fff",
  127. "yyyy-MM-ddTHH:mm:ss.ffff",
  128. "yyyy-MM-ddTHH:mm:ss.fffff",
  129. "yyyy-MM-ddTHH:mm:ss.ffffff",
  130. "yyyy-MM-ddTHH:mm:ss.fffffff",
  131. "yyyy-MM-ddTHH:mm:sszzz",
  132. "yyyy-MM-ddTHH:mm:ss.fzzz",
  133. "yyyy-MM-ddTHH:mm:ss.ffzzz",
  134. "yyyy-MM-ddTHH:mm:ss.fffzzz",
  135. "yyyy-MM-ddTHH:mm:ss.ffffzzz",
  136. "yyyy-MM-ddTHH:mm:ss.fffffzzz",
  137. "yyyy-MM-ddTHH:mm:ss.ffffffzzz",
  138. "yyyy-MM-ddTHH:mm:ss.fffffffzzz",
  139. "yyyy-MM-ddTHH:mm:ssZ",
  140. "yyyy-MM-ddTHH:mm:ss.fZ",
  141. "yyyy-MM-ddTHH:mm:ss.ffZ",
  142. "yyyy-MM-ddTHH:mm:ss.fffZ",
  143. "yyyy-MM-ddTHH:mm:ss.ffffZ",
  144. "yyyy-MM-ddTHH:mm:ss.fffffZ",
  145. "yyyy-MM-ddTHH:mm:ss.ffffffZ",
  146. "yyyy-MM-ddTHH:mm:ss.fffffffZ",
  147. // time
  148. "HH:mm:ss",
  149. "HH:mm:ss.f",
  150. "HH:mm:ss.ff",
  151. "HH:mm:ss.fff",
  152. "HH:mm:ss.ffff",
  153. "HH:mm:ss.fffff",
  154. "HH:mm:ss.ffffff",
  155. "HH:mm:ss.fffffff",
  156. "HH:mm:sszzz",
  157. "HH:mm:ss.fzzz",
  158. "HH:mm:ss.ffzzz",
  159. "HH:mm:ss.fffzzz",
  160. "HH:mm:ss.ffffzzz",
  161. "HH:mm:ss.fffffzzz",
  162. "HH:mm:ss.ffffffzzz",
  163. "HH:mm:ss.fffffffzzz",
  164. "HH:mm:ssZ",
  165. "HH:mm:ss.fZ",
  166. "HH:mm:ss.ffZ",
  167. "HH:mm:ss.fffZ",
  168. "HH:mm:ss.ffffZ",
  169. "HH:mm:ss.fffffZ",
  170. "HH:mm:ss.ffffffZ",
  171. "HH:mm:ss.fffffffZ",
  172. // date
  173. "yyyy-MM-dd",
  174. "yyyy-MM-ddzzz",
  175. "yyyy-MM-ddZ",
  176. // gYearMonth
  177. "yyyy-MM",
  178. "yyyy-MMzzz",
  179. "yyyy-MMZ",
  180. // gYear
  181. "yyyy",
  182. "yyyyzzz",
  183. "yyyyZ",
  184. // gMonthDay
  185. "--MM-dd",
  186. "--MM-ddzzz",
  187. "--MM-ddZ",
  188. // gDay
  189. "---dd",
  190. "---ddzzz",
  191. "---ddZ",
  192. });
  193. }
  194. public static DateTime ToDateTime(string s, string format)
  195. {
  196. DateTimeFormatInfo d = new DateTimeFormatInfo();
  197. d.FullDateTimePattern = format;
  198. return DateTime.Parse(s, d);
  199. }
  200. public static DateTime ToDateTime(string s, string[] formats)
  201. {
  202. DateTimeStyles style = DateTimeStyles.AllowLeadingWhite |
  203. DateTimeStyles.AllowTrailingWhite;
  204. return DateTime.ParseExact (s, formats, DateTimeFormatInfo.InvariantInfo, style);
  205. }
  206. public static Decimal ToDecimal(string s)
  207. {
  208. return Decimal.Parse(s, CultureInfo.InvariantCulture);
  209. }
  210. public static double ToDouble(string s)
  211. {
  212. if (s == "INF") return System.Double.PositiveInfinity;
  213. if (s == "-INF") return System.Double.NegativeInfinity;
  214. if (s == "NaN") return System.Double.NaN;
  215. return Double.Parse(s, CultureInfo.InvariantCulture);
  216. }
  217. public static Guid ToGuid(string s)
  218. {
  219. return new Guid(s);
  220. }
  221. public static short ToInt16(string s)
  222. {
  223. return Int16.Parse(s, CultureInfo.InvariantCulture);
  224. }
  225. public static int ToInt32(string s)
  226. {
  227. return Int32.Parse(s, CultureInfo.InvariantCulture);
  228. }
  229. public static long ToInt64(string s)
  230. {
  231. return Int64.Parse(s, CultureInfo.InvariantCulture);
  232. }
  233. [CLSCompliant (false)]
  234. public static SByte ToSByte(string s)
  235. {
  236. return SByte.Parse(s, CultureInfo.InvariantCulture);
  237. }
  238. public static float ToSingle(string s)
  239. {
  240. if (s == "INF") return System.Single.PositiveInfinity;
  241. if (s == "-INF") return System.Single.NegativeInfinity;
  242. if (s == "NaN") return System.Single.NaN;
  243. return Single.Parse(s, CultureInfo.InvariantCulture);
  244. }
  245. public static string ToString(Guid value)
  246. {
  247. return value.ToString("D",CultureInfo.InvariantCulture);
  248. }
  249. public static string ToString(int value)
  250. {
  251. return value.ToString(CultureInfo.InvariantCulture);
  252. }
  253. public static string ToString(short value)
  254. {
  255. return value.ToString(CultureInfo.InvariantCulture);
  256. }
  257. public static string ToString(byte value)
  258. {
  259. return value.ToString(CultureInfo.InvariantCulture);
  260. }
  261. public static string ToString(long value)
  262. {
  263. return value.ToString(CultureInfo.InvariantCulture);
  264. }
  265. public static string ToString(char value)
  266. {
  267. return value.ToString(CultureInfo.InvariantCulture);
  268. }
  269. public static string ToString(bool value)
  270. {
  271. if (value) return "true";
  272. return "false";
  273. }
  274. [CLSCompliant (false)]
  275. public static string ToString(SByte value)
  276. {
  277. return value.ToString(CultureInfo.InvariantCulture);
  278. }
  279. public static string ToString(Decimal value)
  280. {
  281. return value.ToString(CultureInfo.InvariantCulture);
  282. }
  283. [CLSCompliant (false)]
  284. public static string ToString(UInt64 value)
  285. {
  286. return value.ToString(CultureInfo.InvariantCulture);
  287. }
  288. public static string ToString(TimeSpan value)
  289. {
  290. StringBuilder builder = new StringBuilder();
  291. if (value.Ticks < 0) {
  292. builder.Append('-');
  293. value = value.Negate();
  294. }
  295. builder.Append('P');
  296. if (value.Days > 0) builder.Append(value.Days).Append('D');
  297. if (value.Days > 0 || value.Minutes > 0 || value.Seconds > 0 || value.Milliseconds > 0) {
  298. builder.Append('T');
  299. if (value.Hours > 0) builder.Append(value.Hours).Append('D');
  300. if (value.Minutes > 0) builder.Append(value.Minutes).Append('M');
  301. if (value.Seconds > 0 || value.Milliseconds > 0) {
  302. builder.Append(value.Seconds);
  303. if (value.Milliseconds > 0) builder.Append('.').Append(String.Format("{0:000}", value.Milliseconds));
  304. builder.Append('S');
  305. }
  306. }
  307. return builder.ToString();
  308. }
  309. public static string ToString(double value)
  310. {
  311. if (Double.IsNegativeInfinity(value)) return "-INF";
  312. if (Double.IsPositiveInfinity(value)) return "INF";
  313. if (Double.IsNaN(value)) return "INF";
  314. return value.ToString(CultureInfo.InvariantCulture);
  315. }
  316. public static string ToString(float value)
  317. {
  318. if (Single.IsNegativeInfinity(value)) return "-INF";
  319. if (Single.IsPositiveInfinity(value)) return "INF";
  320. if (Single.IsNaN(value)) return "INF";
  321. return value.ToString(CultureInfo.InvariantCulture);
  322. }
  323. [CLSCompliant (false)]
  324. public static string ToString(UInt32 value)
  325. {
  326. return value.ToString(CultureInfo.InvariantCulture);
  327. }
  328. [CLSCompliant (false)]
  329. public static string ToString(UInt16 value)
  330. {
  331. return value.ToString(CultureInfo.InvariantCulture);
  332. }
  333. public static string ToString(DateTime value)
  334. {
  335. return value.ToString("yyyy-MM-ddTHH:mm:sszzz", CultureInfo.InvariantCulture);
  336. }
  337. public static string ToString(DateTime value, string format)
  338. {
  339. return value.ToString(format, CultureInfo.InvariantCulture);
  340. }
  341. [MonoTODO]
  342. public static TimeSpan ToTimeSpan(string s)
  343. {
  344. return TimeSpan.Parse(s); // FIXME: Should Parse according to XML Schema spec
  345. }
  346. [CLSCompliant (false)]
  347. public static UInt16 ToUInt16(string s)
  348. {
  349. return UInt16.Parse(s, CultureInfo.InvariantCulture);
  350. }
  351. [CLSCompliant (false)]
  352. public static UInt32 ToUInt32(string s)
  353. {
  354. return UInt32.Parse(s, CultureInfo.InvariantCulture);
  355. }
  356. [CLSCompliant (false)]
  357. public static UInt64 ToUInt64(string s)
  358. {
  359. return UInt64.Parse(s, CultureInfo.InvariantCulture);
  360. }
  361. public static string VerifyName(string name)
  362. {
  363. Exception innerEx;
  364. if(name == null)
  365. throw new ArgumentNullException("name");
  366. if(XmlConstructs.IsValidName(name, out innerEx))
  367. return name;
  368. throw new XmlException("'"+name+"' is not a valid XML Name",null);
  369. }
  370. public static string VerifyNCName(string ncname)
  371. {
  372. Exception innerEx;
  373. if(ncname == null)
  374. throw new ArgumentNullException("ncname");
  375. if(XmlConstructs.IsValidName(ncname, out innerEx))
  376. return ncname;
  377. throw new XmlException("'"+ncname+"' is not a valid XML NCName",innerEx);
  378. }
  379. }
  380. }