Merge pull request #2417 from razzfazz/guard_substr
[mono.git] / mcs / tools / mono-xsd / MonoXSD.cs
1 ///\r
2 /// MonoXSD.cs -- A reflection-based tool for dealing with XML Schema.\r
3 ///\r
4 /// Author: Duncan Mak (duncan@ximian.com)\r
5 ///\r
6 /// Copyright (C) 2003, Duncan Mak,\r
7 ///                     Ximian, Inc.\r
8 ///\r
9 \r
10 using System;\r
11 using System.Collections;\r
12 using System.Globalization;\r
13 using System.IO;\r
14 using System.Reflection;\r
15 using System.Text;\r
16 using System.Xml;\r
17 using System.Xml.Schema;\r
18 using System.Xml.Serialization;\r
19 \r
20 namespace Mono.Util {\r
21 \r
22         public class Driver {\r
23 \r
24                 public static readonly string helpString =\r
25                         "MonoXSD.exe - a utility for generating schema or class files\n\nMonoXSD.exe <assembly>.dll|<assembly>.exe [/output:] [/type]\n";\r
26 \r
27                 static void Main (string [] args) {\r
28 \r
29                         if (args.Length < 1) {\r
30                                 Console.WriteLine (helpString);\r
31                                 Environment.Exit (0);\r
32                         }\r
33 \r
34                         string input = args [0];\r
35                         string lookup_type = null;\r
36                         string output_dir = null;\r
37 \r
38                         if (input.EndsWith (".dll") || input.EndsWith (".exe")) {\r
39 \r
40                                 if (args.Length >= 2 && args [1].StartsWith ("/o"))\r
41                                         output_dir = args [1].Substring (args [1].IndexOf (':') + 1);\r
42 \r
43                                 if (args.Length >= 3 && args [2].StartsWith ("/t"))\r
44                                         lookup_type = args [2].Substring (args [2].IndexOf (':') + 1);\r
45 \r
46                                 MonoXSD xsd = new MonoXSD ();\r
47 \r
48                                 try {\r
49                                         xsd.WriteSchema (input, lookup_type, output_dir);\r
50                                 } catch (ArgumentException e) {\r
51                                         Console.WriteLine (e.Message + "\n");\r
52                                         Environment.Exit (0);\r
53                                 }\r
54                         } else {\r
55                                 Console.WriteLine ("Not supported.");\r
56                                 return;\r
57                         }\r
58                 }\r
59         }\r
60 \r
61 \r
62         public class MonoXSD {\r
63                 Hashtable attributes;\r
64                 int fileCount = 0;\r
65                 bool isText = false;\r
66                 BindingFlags flags = BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly;\r
67                 XmlSchema schema = new XmlSchema ();\r
68                 readonly string xs = "http://www.w3.org/2001/XMLSchema";\r
69                 Hashtable generatedSchemaTypes;\r
70 \r
71                 public int FileCount {\r
72                         set { fileCount = value; }\r
73                 }\r
74 \r
75                 /// <summary>\r
76                 ///     Writes a schema for each type in the assembly\r
77                 /// </summary>\r
78                 public void WriteSchema (string assembly, string lookup_type, string output_dir) {\r
79 \r
80                         Assembly a;\r
81 \r
82                         try {\r
83                                 a = Assembly.LoadFrom (assembly);\r
84                         } catch (Exception e) {\r
85                                 Console.WriteLine ("Cannot use {0}, {1}", assembly, e.Message);\r
86                                 return;\r
87                         }\r
88 \r
89                         generatedSchemaTypes = new Hashtable ();\r
90 \r
91                         XmlSchemaType schemaType;\r
92 \r
93                         foreach (Type t in a.GetTypes ()) {\r
94 \r
95                                 if (lookup_type != null && t.Name != lookup_type)\r
96                                         continue;\r
97 \r
98                                 try {\r
99                                         schemaType = WriteSchemaType (t);\r
100                                 } catch (ArgumentException e) {\r
101                                         throw new ArgumentException (String.Format ("Error: We cannot process {0}\n{1}", assembly, e.Message));\r
102                                 }\r
103 \r
104                                 if (schemaType == null)\r
105                                         continue; // skip\r
106 \r
107                                 XmlSchemaElement schemaElement = WriteSchemaElement (t, schemaType);\r
108                                 schema.Items.Add (schemaElement);\r
109                                 schema.Items.Add (schemaType);\r
110                         }\r
111 \r
112                         schema.ElementFormDefault = XmlSchemaForm.Qualified;\r
113                         schema.Compile (new ValidationEventHandler (OnSchemaValidation));\r
114 \r
115                         string output = String.Format ("schema{0}.xsd", fileCount);\r
116 \r
117                         if (output_dir != null)\r
118                                 output = Path.Combine (output_dir, output);\r
119 \r
120                         XmlTextWriter writer = new XmlTextWriter (output, Encoding.UTF8);\r
121                         writer.Formatting = Formatting.Indented;\r
122                         schema.Write (writer);\r
123                         Console.WriteLine ("\nWriting {0}.", output);\r
124                 }\r
125 \r
126                 /// <summary>\r
127                 ///     Given a Type and its associated schema type, add aa '<xs;element>' node\r
128                 ///     to the schema.\r
129                 /// </summary>\r
130                 public XmlSchemaElement WriteSchemaElement (Type type, XmlSchemaType schemaType)\r
131                 {\r
132                         XmlSchemaElement schemaElement = new XmlSchemaElement ();\r
133                         schemaElement.Name = type.Name;\r
134 \r
135                         if (schemaType.QualifiedName == null)\r
136                                 schemaElement.SchemaTypeName = new XmlQualifiedName (schemaType.Name);\r
137 \r
138                         else\r
139                                 schemaElement.SchemaTypeName = schemaType.QualifiedName;\r
140 \r
141                         if (schemaType is XmlSchemaComplexType)\r
142                                 schemaElement.IsNillable = true;\r
143 \r
144                         return schemaElement;\r
145                 }\r
146 \r
147                 public void OnSchemaValidation (object sender, ValidationEventArgs args)\r
148                 {\r
149                         Console.WriteLine (args.Message);\r
150                 }\r
151 \r
152 \r
153                 /// <summary>\r
154                 ///     From a Type, create a corresponding ComplexType node to\r
155                 ///     represent this Type.\r
156                 /// </summary>\r
157                 public XmlSchemaType WriteSchemaType (Type type)\r
158                 {\r
159                         if (generatedSchemaTypes.Contains (type.FullName)) // Caching\r
160                                 return generatedSchemaTypes [type.FullName] as XmlSchemaType;\r
161 \r
162                         XmlSchemaType schemaType = new XmlSchemaType ();\r
163 \r
164                         attributes = new Hashtable ();\r
165 \r
166                         if (!type.IsAbstract && typeof (System.Delegate).IsAssignableFrom (type))\r
167                                 return null;\r
168 \r
169                         if (type.IsEnum)\r
170                                 return WriteEnumType (type);\r
171 \r
172                         else if (type != typeof (object) && type.BaseType != typeof (object)) {\r
173                                 try {\r
174                                         schemaType = WriteComplexSchemaType (type);\r
175                                 } catch (ArgumentException e) {\r
176                                         throw e;\r
177                                 }\r
178 \r
179                         } else {\r
180 \r
181                                 XmlSchemaComplexType complexType = new XmlSchemaComplexType ();\r
182                                 complexType.Name = type.Name;\r
183                                 FieldInfo [] fields = type.GetFields (flags);\r
184                                 PropertyInfo [] properties = type.GetProperties (flags);\r
185                                 XmlSchemaSequence sequence;\r
186 \r
187                                 try {\r
188                                         sequence = PopulateSequence (fields, properties);\r
189 \r
190                                         if (attributes != null) {\r
191                                                 foreach (object o in attributes.Keys) {\r
192                                                         MemberInfo member = o as MemberInfo;\r
193                                                         Type attribute_type = attributes [o] as Type;\r
194 \r
195                                                         if (attribute_type == typeof (System.Xml.Schema.XmlSchemaAnyAttribute))\r
196                                                                 complexType.AnyAttribute = new XmlSchemaAnyAttribute ();\r
197                                                         else\r
198                                                                 complexType.Attributes.Add (WriteSchemaAttribute (member, attribute_type));\r
199                                                 }\r
200                                         }\r
201 \r
202                                 } catch (ArgumentException e) {\r
203                                         throw new ArgumentException (String.Format ("There is an error in '{0}'\n\t{1}", type.Name, e.Message));\r
204                                 }\r
205 \r
206                                 if (isText) {\r
207                                         complexType.IsMixed = true;\r
208                                         isText = false;\r
209                                 }\r
210 \r
211                                 complexType.Particle = sequence;\r
212                                 generatedSchemaTypes.Add (type.FullName, complexType);\r
213 \r
214                                 schemaType = complexType;\r
215                         }\r
216 \r
217                         return schemaType;\r
218                 }\r
219 \r
220                 public XmlSchemaAttribute WriteSchemaAttribute (MemberInfo member, Type attribute_type)\r
221                 {\r
222                         if (member == null || attribute_type == null)\r
223                                 return null;\r
224 \r
225                         XmlSchemaAttribute attribute = new XmlSchemaAttribute ();\r
226                         attribute.Name = member.Name;\r
227                         attribute.SchemaTypeName = GetQualifiedName (attribute_type.FullName);\r
228 \r
229                         object [] attrs = member.GetCustomAttributes (false);\r
230 \r
231                         return attribute;\r
232                 }\r
233 \r
234                 public XmlSchemaType WriteEnumType (Type type)\r
235                 {\r
236                         if (type.IsEnum == false)\r
237                                 throw new Exception (String.Format ("{0} is not an enumeration.", type.Name));\r
238 \r
239                         if (generatedSchemaTypes.Contains (type.FullName)) // Caching\r
240                                 return null;\r
241 \r
242                         XmlSchemaSimpleType simpleType = new XmlSchemaSimpleType ();\r
243                         simpleType.Name = type.Name;\r
244                         FieldInfo [] fields = type.GetFields ();\r
245 \r
246                         XmlSchemaSimpleTypeRestriction simpleRestriction = new XmlSchemaSimpleTypeRestriction ();\r
247                         simpleType.Content = simpleRestriction;\r
248                         simpleRestriction.BaseTypeName = new XmlQualifiedName ("string", xs);\r
249 \r
250                         foreach (FieldInfo field in fields) {\r
251                                 if (field.IsSpecialName)\r
252                                         continue;\r
253 \r
254                                 XmlSchemaEnumerationFacet e = new XmlSchemaEnumerationFacet ();\r
255                                 e.Value = field.Name;\r
256                                 simpleRestriction.Facets.Add (e);\r
257                         }\r
258 \r
259                         generatedSchemaTypes.Add (type.FullName, simpleType);\r
260                         return simpleType;\r
261                 }\r
262 \r
263                 public XmlSchemaType WriteArrayType (Type type, MemberInfo member)\r
264                 {\r
265                         if (generatedSchemaTypes.Contains (type.FullName)) // Caching\r
266                                 return null;\r
267 \r
268                         XmlSchemaComplexType complexType = new XmlSchemaComplexType ();\r
269 \r
270                         XmlQualifiedName qname = GetQualifiedName (type);\r
271 \r
272                         if (qname == null)\r
273                                 complexType.Name = type.Name;\r
274                         else\r
275                                 complexType.Name = qname.Name;\r
276 \r
277                         XmlSchemaSequence sequence = new XmlSchemaSequence ();\r
278                         XmlSchemaElement element = new XmlSchemaElement ();\r
279 \r
280                         element.MinOccurs = 0;\r
281                         element.MaxOccursString = "unbounded";\r
282                         element.IsNillable = true;\r
283                         element.Name = qname.Name.ToLower ();\r
284 \r
285                         object [] attrs = member.GetCustomAttributes (false);\r
286 \r
287                         if (attrs.Length > 0) {\r
288                                 foreach (object o in attrs) {\r
289                                         if (o is XmlArrayItemAttribute) {\r
290                                                 if (type.IsArray == false)\r
291                                                         throw new ArgumentException (\r
292                                                                 String.Format ("XmlArrayAttribute is not applicable to {0}, because it is not an array.",\r
293                                                                 member.Name));\r
294 \r
295                                                 XmlArrayItemAttribute attr = (XmlArrayItemAttribute) o;\r
296 \r
297                                                 if (attr.ElementName.Length != 0)\r
298                                                         element.Name = attr.ElementName;\r
299 \r
300                                                 continue;\r
301                                         }\r
302 \r
303                                         if (o is XmlAnyElementAttribute)\r
304                                                 return null;\r
305                                 }\r
306                         }\r
307 \r
308                         element.SchemaTypeName = GetQualifiedName (\r
309                                 type.FullName.Substring (0, type.FullName.Length - 2));\r
310 \r
311                         sequence.Items.Add (element);\r
312                         complexType.Particle = sequence;\r
313 \r
314                         generatedSchemaTypes.Add (type.FullName, complexType);\r
315                         return complexType;\r
316                 }\r
317 \r
318                 public XmlSchemaType WriteComplexSchemaType ()\r
319                 {\r
320                         XmlSchemaComplexType complexType = new XmlSchemaComplexType ();\r
321                         XmlSchemaSequence sequence;\r
322                         complexType.IsMixed = true;\r
323                         sequence = new XmlSchemaSequence ();\r
324                         sequence.Items.Add (new XmlSchemaAny ());\r
325                         complexType.Particle = sequence;\r
326                         return complexType;\r
327                 }\r
328 \r
329 \r
330                 /// <summary>\r
331                 ///     Handle derivation by extension.\r
332                 ///     If type is null, it'll create a new complexType\r
333                 ///     with an XmlAny node in its sequence child node.\r
334                 /// </summary>\r
335                 public XmlSchemaType WriteComplexSchemaType (Type type)\r
336                 {\r
337                         //\r
338                         // Recursively generate schema for all parent types\r
339                         //\r
340                         if (type != null && type.BaseType == typeof (object))\r
341                                 return WriteSchemaType (type);\r
342 \r
343                         XmlSchemaComplexType complexType = new XmlSchemaComplexType ();\r
344                         XmlSchemaSequence sequence;\r
345                         XmlSchemaComplexContentExtension extension = new XmlSchemaComplexContentExtension ();\r
346                         XmlSchemaComplexContent content = new XmlSchemaComplexContent ();\r
347 \r
348                         complexType.ContentModel = content;\r
349                         content.Content = extension;\r
350 \r
351                         XmlSchemaType baseSchemaType = WriteSchemaType (type.BaseType);\r
352 \r
353                         complexType.Name = type.Name;\r
354 \r
355                         FieldInfo [] fields = type.GetFields (flags);\r
356                         PropertyInfo [] properties = type.GetProperties (flags);\r
357 \r
358                         try {\r
359                                 sequence = PopulateSequence (fields, properties);\r
360                                 if (attributes != null) {\r
361                                         foreach (object o in attributes) {\r
362                                                 MemberInfo member = (MemberInfo) o;\r
363                                                 Type attribute_type = (Type) attributes [o];\r
364 \r
365                                                 complexType.Attributes.Add (WriteSchemaAttribute (member, attribute_type));\r
366                                         }\r
367                                 }\r
368                         } catch (ArgumentException e) {\r
369                                 throw new ArgumentException (String.Format ("There is an error in '{0}'\n\t{1}", type.Name, e.Message));\r
370                         }\r
371 \r
372                         extension.BaseTypeName = new XmlQualifiedName (baseSchemaType.Name);\r
373                         extension.Particle = sequence;\r
374 \r
375                         generatedSchemaTypes.Add (type.FullName, complexType);\r
376                         return complexType;\r
377                 }\r
378 \r
379                 public XmlSchemaSequence PopulateSequence (FieldInfo [] fields, PropertyInfo [] properties)\r
380                 {\r
381                         if (fields.Length == 0 && properties.Length == 0)\r
382                                 return null;\r
383 \r
384                         XmlSchemaSequence sequence = new XmlSchemaSequence ();\r
385 \r
386                         try {\r
387                                 foreach (FieldInfo field in fields)\r
388                                         if (IsXmlAttribute (field))\r
389                                                 attributes.Add (field, field.FieldType);\r
390                                         else if (IsXmlAnyAttribute (field))\r
391                                                 attributes.Add (field,\r
392                                                         typeof (System.Xml.Schema.XmlSchemaAnyAttribute));\r
393                                         else\r
394                                                 AddElement (sequence, field, field.FieldType);\r
395 \r
396                         } catch (Exception e) {\r
397                                 throw e;\r
398                         }\r
399 \r
400                         if (properties.Length == 0)\r
401                                 return sequence;\r
402                         try {\r
403                                 foreach (PropertyInfo property in properties)\r
404                                         if (IsXmlAttribute (property))\r
405                                                 attributes.Add (property, property.PropertyType);\r
406                                         else if (IsXmlAnyAttribute (property))\r
407                                                 attributes.Add (property,\r
408                                                         typeof (System.Xml.Schema.XmlSchemaAnyAttribute));\r
409                                         else {\r
410                                                 AddElement (sequence, property, property.PropertyType);\r
411                                         }\r
412 \r
413                         } catch (ArgumentException e) {\r
414                                 throw e;\r
415                         }\r
416 \r
417                         return sequence;\r
418                 }\r
419 \r
420                 public bool IsXmlAttribute (MemberInfo member)\r
421                 {\r
422                         object [] attrs = member.GetCustomAttributes (\r
423                                 typeof (System.Xml.Serialization.XmlAttributeAttribute), false);\r
424 \r
425                         if (attrs.Length == 0)\r
426                                 return false;\r
427                         else\r
428                                 return true;\r
429                 }\r
430 \r
431                 public bool IsXmlAnyAttribute (MemberInfo member) {\r
432                         object [] attrs = member.GetCustomAttributes (\r
433                                 typeof (System.Xml.Serialization.XmlAnyAttributeAttribute), false);\r
434 \r
435                         if (attrs.Length == 0)\r
436                                 return false;\r
437                         else\r
438                                 return true;\r
439                 }\r
440 \r
441                 ///<summary>\r
442                 ///     Populates element nodes inside a '<xs:sequence>' node.\r
443                 ///</summary>\r
444                 public void AddElement (XmlSchemaSequence sequence, MemberInfo member, Type type)\r
445                 {\r
446                         //\r
447                         // Only read/write properties are supported.\r
448                         //\r
449                         if (member is PropertyInfo) {\r
450                                 PropertyInfo p = (PropertyInfo) member;\r
451                                 if ((p.CanRead && p.CanWrite) == false)\r
452                                         return;\r
453                         }\r
454 \r
455                         //\r
456                         // readonly fields are not supported.\r
457                         //\r
458                         if (member is FieldInfo) {\r
459                                 FieldInfo f = (FieldInfo) member;\r
460                                 if (f.IsInitOnly || f.IsLiteral)\r
461                                         return;\r
462                         }\r
463 \r
464                         //\r
465                         // delegates are not supported.\r
466                         //\r
467                         if (!type.IsAbstract && typeof (System.Delegate).IsAssignableFrom (type))\r
468                                 return;\r
469 \r
470                         //\r
471                         // If it's an array, write a SchemaType for the type of array\r
472                         //\r
473                         if (type.IsArray) {\r
474                                 XmlSchemaType arrayType = WriteArrayType (type, member);\r
475                                 if (arrayType != null)\r
476                                         schema.Items.Add (arrayType);\r
477                         }\r
478 \r
479                         XmlSchemaElement element = new XmlSchemaElement ();\r
480 \r
481                         element.Name = member.Name;\r
482                         XmlQualifiedName schema_type_name = GetQualifiedName (type);\r
483 \r
484                          if (type.IsEnum) {\r
485                                 element.SchemaTypeName = new XmlQualifiedName (type.Name);\r
486 \r
487                          } else if (schema_type_name.Name == "xml") {\r
488                                  element.SchemaType = WriteComplexSchemaType ();\r
489                                  element.SchemaTypeName = XmlQualifiedName.Empty; // 'xml' is just a temporary name\r
490 \r
491                          } else if (schema_type_name == null) {\r
492                                 throw new ArgumentException (String.Format ("The type '{0}' cannot be represented in XML Schema.", type.FullName));\r
493 \r
494                          } else  // this is the normal case\r
495                                 element.SchemaTypeName = schema_type_name;\r
496 \r
497                         object [] attrs = member.GetCustomAttributes (false);\r
498 \r
499                         if (attrs.Length > 0) {\r
500                                 foreach (object o in attrs) {\r
501                                         if (o is XmlElementAttribute) {\r
502                                                 XmlElementAttribute attr = (XmlElementAttribute) o;\r
503 \r
504                                                 if (attr.DataType != null && attr.DataType.Length != 0)\r
505                                                         element.SchemaTypeName = new XmlQualifiedName (attr.DataType, xs);\r
506                                                 if (attr.ElementName != null && attr.ElementName.Length != 0)\r
507                                                         element.Name = attr.ElementName;\r
508 \r
509                                                 continue;\r
510                                         }\r
511 \r
512                                         if (o is XmlArrayAttribute) {\r
513 \r
514                                                 if (type.IsArray == false)\r
515                                                         throw new ArgumentException (\r
516                                                                 String.Format ("XmlArrayAttribute is not applicable to {0}, because it is not an array.",\r
517                                                                                 member.Name));\r
518 \r
519                                                 XmlArrayAttribute attr = (XmlArrayAttribute) o;\r
520 \r
521                                                 if (attr.ElementName.Length != 0)\r
522                                                         element.Name = attr.ElementName;\r
523 \r
524                                                 continue;\r
525                                         }\r
526 \r
527                                         //\r
528                                         // isText signals that the mixed="true" in the schema type.\r
529                                         //\r
530                                         if (o is XmlTextAttribute) {\r
531                                                 isText = true;\r
532                                                 return;\r
533                                         }\r
534 \r
535                                         if (o is XmlAnyElementAttribute) {\r
536                                                 XmlSchemaAny any = new XmlSchemaAny ();\r
537                                                 any.MinOccurs = 0;\r
538                                                 any.MaxOccursString = "unbounded";\r
539                                                 sequence.Items.Add (any);\r
540                                                 return;\r
541                                         }\r
542                                 }\r
543                         }\r
544 \r
545                         if (type.IsClass)\r
546                                 element.MinOccurs = 0;\r
547                         else if (type.IsValueType)\r
548                                 element.MinOccurs = 1;\r
549 \r
550                         element.MaxOccurs = 1;\r
551 \r
552                         sequence.Items.Add (element);\r
553                 }\r
554 \r
555                 public XmlQualifiedName GetQualifiedName (Type type)\r
556                 {\r
557                         //\r
558                         // XmlAttributes are not saved.\r
559                         //\r
560                         if (type.Equals (typeof (System.Xml.XmlAttribute)))\r
561                                 return null;\r
562 \r
563                         //\r
564                         // Other derivatives of XmlNode are saved specially,\r
565                         // as indicated by this "xml" flag.\r
566                         //\r
567                         if (type.Equals (typeof (System.Xml.XmlNode))\r
568                                 || type.IsSubclassOf (typeof (System.Xml.XmlNode)))\r
569                                 return new XmlQualifiedName ("xml");\r
570 \r
571                         if (type.IsArray) {\r
572                                 TextInfo ti = CultureInfo.CurrentCulture.TextInfo;\r
573                                 string type_name = type.FullName.Substring (0, type.FullName.Length - 2);\r
574 \r
575                                 XmlQualifiedName qname = GetQualifiedName (type_name);\r
576                                 string array_type;\r
577 \r
578                                 if (qname != null)\r
579                                         array_type = ti.ToTitleCase (qname.Name);\r
580                                 else\r
581                                         array_type = ti.ToTitleCase (type.Name.Substring (0, type.Name.Length - 2));\r
582 \r
583                                 return new XmlQualifiedName ("ArrayOf" + array_type);\r
584                         }\r
585 \r
586                         return GetQualifiedName (type.FullName);\r
587                 }\r
588 \r
589                 public XmlQualifiedName GetQualifiedName (string type)\r
590                 {\r
591                         string type_name;\r
592 \r
593                         switch (type) {\r
594                                 case "System.Uri":\r
595                                         type_name =  "anyURI";\r
596                                         break;\r
597                                 case "System.Boolean":\r
598                                         type_name = "Boolean";\r
599                                         break;\r
600                                 case "System.SByte":\r
601                                         type_name = "Byte";\r
602                                         break;\r
603                                 case "System.DateTime":\r
604                                         type_name = "dateTime";\r
605                                         break;\r
606                                 case "System.Decimal":\r
607                                         type_name = "decimal";\r
608                                         break;\r
609                                 case "System.Double":\r
610                                         type_name = "Double";\r
611                                         break;\r
612                                 case "System.Int16":\r
613                                         type_name = "short";\r
614                                         break;\r
615                                 case "System.Int32":\r
616                                         type_name =  "int";\r
617                                         break;\r
618                                 case "System.Int64":\r
619                                         type_name = "long";\r
620                                         break;\r
621                                 case "System.Xml.XmlQualifiedName":\r
622                                         type_name = "QName";\r
623                                         break;\r
624                                 case "System.TimeSpan":\r
625                                         type_name = "duration";\r
626                                         break;\r
627                                 case "System.String":\r
628                                         type_name = "string";\r
629                                         break;\r
630                                 case "System.UInt16":\r
631                                         type_name = "unsignedShort";\r
632                                         break;\r
633                                 case "System.UInt32":\r
634                                         type_name = "unsignedInt";\r
635                                         break;\r
636                                 case "System.UInt64":\r
637                                         type_name = "unsignedLong";\r
638                                         break;\r
639                                 default:\r
640                                         type_name = null;\r
641                                         break;\r
642                         }\r
643 \r
644                         if (type_name == null)\r
645                                 return null;\r
646 \r
647                         else {\r
648                                 XmlQualifiedName name = new XmlQualifiedName (type_name, xs);\r
649                                 return name;\r
650                         }\r
651                 }\r
652         }\r
653 }\r