2 // XmlSchemaInference.cs
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.
34 using System.Collections;
36 using System.Xml.Schema;
38 using QName = System.Xml.XmlQualifiedName;
39 using Form = System.Xml.Schema.XmlSchemaForm;
40 using Use = System.Xml.Schema.XmlSchemaUse;
41 using SOMList = System.Xml.Schema.XmlSchemaObjectCollection;
42 using SOMObject = System.Xml.Schema.XmlSchemaObject;
43 using Element = System.Xml.Schema.XmlSchemaElement;
44 using Attr = System.Xml.Schema.XmlSchemaAttribute;
45 using AttrGroup = System.Xml.Schema.XmlSchemaAttributeGroup;
46 using AttrGroupRef = System.Xml.Schema.XmlSchemaAttributeGroupRef;
47 using SimpleType = System.Xml.Schema.XmlSchemaSimpleType;
48 using ComplexType = System.Xml.Schema.XmlSchemaComplexType;
49 using SimpleModel = System.Xml.Schema.XmlSchemaSimpleContent;
50 using SimpleExt = System.Xml.Schema.XmlSchemaSimpleContentExtension;
51 using SimpleRst = System.Xml.Schema.XmlSchemaSimpleContentRestriction;
52 using ComplexModel = System.Xml.Schema.XmlSchemaComplexContent;
53 using ComplexExt = System.Xml.Schema.XmlSchemaComplexContentExtension;
54 using ComplexRst = System.Xml.Schema.XmlSchemaComplexContentRestriction;
55 using SimpleTypeRst = System.Xml.Schema.XmlSchemaSimpleTypeRestriction;
56 using SimpleList = System.Xml.Schema.XmlSchemaSimpleTypeList;
57 using SimpleUnion = System.Xml.Schema.XmlSchemaSimpleTypeUnion;
58 using SchemaFacet = System.Xml.Schema.XmlSchemaFacet;
59 using LengthFacet = System.Xml.Schema.XmlSchemaLengthFacet;
60 using MinLengthFacet = System.Xml.Schema.XmlSchemaMinLengthFacet;
61 using Particle = System.Xml.Schema.XmlSchemaParticle;
62 using Sequence = System.Xml.Schema.XmlSchemaSequence;
63 using Choice = System.Xml.Schema.XmlSchemaChoice;
66 namespace System.Xml.Schema
68 [MonoTODO ("merge primitive types; infer gYearMonth too; in some cases sequence should contain element whose minOccurs=0 (no obvious rules right now); reject some non-supported schema components")]
69 public class XmlSchemaInference
71 public enum InferenceOption {
76 InferenceOption occurrence = InferenceOption.Restricted;
77 InferenceOption typeInference = InferenceOption.Restricted;
79 public XmlSchemaInference ()
83 public InferenceOption Occurrence {
84 get { return occurrence; }
85 set { occurrence = value; }
88 public InferenceOption TypeInference {
89 get { return TypeInference; }
90 set { typeInference = value; }
93 public XmlSchemaSet InferSchema (XmlReader xmlReader)
95 return InferSchema (xmlReader, new XmlSchemaSet ());
98 public XmlSchemaSet InferSchema (XmlReader xmlReader,
101 return XsdInference.Process (xmlReader, schemas,
102 occurrence == InferenceOption.Relaxed,
103 typeInference == InferenceOption.Relaxed);
109 public static XmlSchemaSet Process (XmlReader xmlReader,
110 XmlSchemaSet schemas,
112 bool laxTypeInference)
114 XsdInference impl = new XsdInference (xmlReader,
115 schemas, laxOccurence, laxTypeInference);
120 public const string NamespaceXml = "http://www.w3.org/XML/1998/namespace";
122 public const string NamespaceXmlns = "http://www.w3.org/2000/xmlns/";
124 public const string XdtNamespace = "http://www.w3.org/2003/11/xpath-datatypes";
126 static readonly QName QNameString = new QName ("string",
127 XmlSchema.Namespace);
129 static readonly QName QNameBoolean = new QName ("boolean",
130 XmlSchema.Namespace);
132 static readonly QName QNameAnyType = new QName ("anyType",
133 XmlSchema.Namespace);
136 XmlSchemaSet schemas;
138 bool laxTypeInference;
140 Hashtable newElements = new Hashtable ();
141 Hashtable newAttributes = new Hashtable ();
143 private XsdInference (XmlReader xmlReader,
144 XmlSchemaSet schemas,
146 bool laxTypeInference)
148 this.source = xmlReader;
149 this.schemas = schemas;
150 this.laxOccurence = laxOccurence;
151 this.laxTypeInference = laxTypeInference;
156 // XmlSchemaSet need to be compiled.
159 // move to top-level element
160 source.MoveToContent ();
161 int depth = source.Depth;
162 if (source.NodeType != XmlNodeType.Element)
163 throw new ArgumentException ("Argument XmlReader content is expected to be an element.");
165 QName qname = new QName (source.LocalName,
166 source.NamespaceURI);
167 Element el = GetGlobalElement (qname);
169 el = CreateGlobalElement (qname);
170 InferElement (el, qname.Namespace, true);
173 InferElement (el, qname.Namespace, false);
176 private void IncludeXmlAttributes ()
178 if (schemas.Schemas (NamespaceXml).Count == 0)
179 // FIXME: do it from resources.
180 schemas.Add (NamespaceXml,
181 "http://www.w3.org/2001/xml.xsd");
184 private void InferElement (Element el, string ns, bool isNew)
186 // Quick check for reference to another definition
187 // (i.e. element ref='...' that should be redirected)
188 if (el.RefName != QName.Empty) {
189 Element body = GetGlobalElement (el.RefName);
191 body = CreateElement (el.RefName);
192 InferElement (body, ns, true);
195 InferElement (body, ns, isNew);
200 if (source.MoveToFirstAttribute ()) {
201 InferAttributes (el, ns, isNew);
202 source.MoveToElement ();
206 if (source.IsEmptyElement) {
207 InferAsEmptyElement (el, ns, isNew);
209 source.MoveToContent ();
212 InferContent (el, ns, isNew);
213 source.ReadEndElement ();
215 if (el.SchemaType == null &&
216 el.SchemaTypeName == QName.Empty)
217 el.SchemaTypeName = QNameString;
220 #region Attribute Inference
222 private Hashtable CollectAttrTable (SOMList attList)
224 // get attribute definition table.
225 Hashtable table = new Hashtable ();
226 foreach (XmlSchemaObject obj in attList) {
227 Attr attr = obj as Attr;
229 throw Error (obj, String.Format ("Attribute inference only supports direct attribute definition. {0} is not supported.", obj.GetType ()));
230 if (attr.RefName != QName.Empty)
231 table.Add (attr.RefName, attr);
233 table.Add (new QName (attr.Name, ""),
239 private void InferAttributes (Element el, string ns, bool isNew)
241 // Now this element is going to have complexType.
242 // It currently not, then we have to replace it.
243 ComplexType ct = null;
244 SOMList attList = null;
245 Hashtable table = null;
248 switch (source.NamespaceURI) {
250 if (schemas.Schemas (
251 NamespaceXml) .Count == 0)
252 IncludeXmlAttributes ();
254 case XmlSchema.InstanceNamespace:
255 if (source.LocalName == "nil")
256 el.IsNillable = true;
257 // all other xsi:* atts are ignored
263 ct = ToComplexType (el);
264 attList = GetAttributes (ct);
265 table = CollectAttrTable (attList);
267 QName attrName = new QName (
268 source.LocalName, source.NamespaceURI);
269 Attr attr = table [attrName] as Attr;
271 attList.Add (InferNewAttribute (
274 table.Remove (attrName);
275 if (attr.RefName != null &&
276 attr.RefName != QName.Empty)
277 continue; // just a reference
278 InferMergedAttribute (attr);
280 } while (source.MoveToNextAttribute ());
282 // mark all attr definitions that did not appear
285 foreach (Attr attr in table.Values)
286 attr.Use = Use.Optional;
289 private XmlSchemaAttribute InferNewAttribute (
290 QName attrName, bool isNewTypeDefinition)
293 bool mergedRequired = false;
294 if (attrName.Namespace.Length > 0) {
295 // global attribute; might be already defined.
296 attr = GetGlobalAttribute (attrName) as Attr;
298 attr = CreateGlobalAttribute (attrName);
299 attr.SchemaTypeName =
300 InferSimpleType (source.Value);
302 InferMergedAttribute (attr);
304 attr.Use == Use.Required;
307 attr.RefName = attrName;
311 attr.Name = attrName.Name;
312 attr.SchemaTypeName =
313 InferSimpleType (source.Value);
316 (isNewTypeDefinition || mergedRequired))
317 attr.Use = Use.Required;
319 attr.Use = Use.Optional;
324 // validate string value agains attr and
325 // if invalid, then relax the type.
326 private void InferMergedAttribute (Attr attr)
328 attr.SchemaTypeName = InferMergedType (source.Value,
329 attr.SchemaTypeName);
330 attr.SchemaType = null;
333 private QName InferMergedType (string value, QName typeName)
335 // examine value against specified type and
336 // if unacceptable, then return a relaxed type.
338 SimpleType st = XmlSchemaType.GetBuiltInSimpleType (
340 if (st == null) // non-primitive type => see above.
343 st.Datatype.ParseValue (value,
345 source as IXmlNamespaceResolver);
346 // the string value was value
349 // The types were incompatible.
350 // FIXME: find the base common type
355 private SOMList GetAttributes (ComplexType ct)
357 if (ct.ContentModel == null)
358 return ct.Attributes;
360 SimpleModel sc = ct.ContentModel as SimpleModel;
362 SimpleExt sce = sc.Content as SimpleExt;
364 return sce.Attributes;
365 SimpleRst scr = sc.Content as SimpleRst;
367 return scr.Attributes;
369 throw Error (sc, "Invalid simple content model.");
371 ComplexModel cc = ct.ContentModel as ComplexModel;
373 ComplexExt cce = cc.Content as ComplexExt;
375 return cce.Attributes;
376 ComplexRst ccr = cc.Content as ComplexRst;
378 return ccr.Attributes;
380 throw Error (cc, "Invalid simple content model.");
382 throw Error (cc, "Invalid complexType. Should not happen.");
385 private ComplexType ToComplexType (Element el)
387 QName name = el.SchemaTypeName;
388 XmlSchemaType type = el.SchemaType;
390 // 1. element type is complex.
391 ComplexType ct = type as ComplexType;
395 // 2. reference to global complexType.
396 XmlSchemaType globalType = schemas.GlobalTypes [name]
398 ct = globalType as ComplexType;
402 ct = new ComplexType ();
404 el.SchemaTypeName = QName.Empty;
406 // 3. base type name is xs:anyType or no specification.
407 // <xs:complexType />
408 if (name == QNameAnyType)
410 else if (type == null && name == QName.Empty)
413 SimpleModel sc = new SimpleModel ();
414 ct.ContentModel = sc;
416 // 4. type is simpleType
417 // -> extension of existing simple type.
418 SimpleType st = type as SimpleType;
420 SimpleRst scr = new SimpleRst ();
426 SimpleExt sce = new SimpleExt ();
429 // 5. type name points to primitive type
430 // -> simple extension of a primitive type
431 st = XmlSchemaType.GetBuiltInSimpleType (name);
433 sce.BaseTypeName = name;
437 // 6. type name points to global simpleType.
438 st = globalType as SimpleType;
440 sce.BaseTypeName = name;
444 throw Error (el, "Unexpected schema component that contains simpleTypeName that could not be resolved.");
451 private void InferAsEmptyElement (Element el, string ns,
454 ComplexType ct = el.SchemaType as ComplexType;
457 ct.ContentModel as SimpleModel;
459 ToEmptiableSimpleContent (sm, isNew);
463 ComplexModel cm = ct.ContentModel
466 ToEmptiableComplexContent (cm, isNew);
470 if (ct.Particle != null)
471 ct.Particle.MinOccurs = 0;
474 SimpleType st = el.SchemaType as SimpleType;
476 st = MakeBaseTypeAsEmptiable (st);
477 switch (st.QualifiedName.Namespace) {
478 case XmlSchema.Namespace:
480 el.SchemaTypeName = st.QualifiedName;
489 private SimpleType MakeBaseTypeAsEmptiable (SimpleType st)
491 switch (st.QualifiedName.Namespace) {
492 case XmlSchema.Namespace:
494 // If a primitive type
495 return XmlSchemaType.GetBuiltInSimpleType (
498 SimpleTypeRst str = st.Content as SimpleTypeRst;
501 foreach (SchemaFacet f in str.Facets) {
502 if (f is LengthFacet ||
503 f is MinLengthFacet) {
505 al = new ArrayList ();
509 foreach (SchemaFacet f in al)
510 str.Facets.Remove (f);
511 if (str.BaseType != null)
513 MakeBaseTypeAsEmptiable (st);
515 // It might have a reference to an
516 // external simple type, but there is
517 // no assurance that any of those
518 // external types allow an empty
519 // string. So just set base type as
521 str.BaseTypeName = QNameString;
522 } // union/list can have empty string value.
527 private void ToEmptiableSimpleContent (
528 SimpleModel sm, bool isNew)
530 SimpleExt se = sm.Content as SimpleExt;
532 se.BaseTypeName = QNameString;
534 SimpleRst sr = sm.Content
537 throw Error (sm, "Invalid simple content model was passed.");
538 sr.BaseTypeName = QNameString;
543 private void ToEmptiableComplexContent (
544 ComplexModel cm, bool isNew)
546 ComplexExt ce = cm.Content
549 if (ce.Particle != null)
550 ce.Particle.MinOccurs = 0;
551 else if (ce.BaseTypeName != null &&
552 ce.BaseTypeName != QName.Empty &&
553 ce.BaseTypeName != QNameAnyType)
554 throw Error (ce, "Complex type content extension has a reference to an external component that is not supported.");
557 ComplexRst cr = cm.Content
560 throw Error (cm, "Invalid complex content model was passed.");
561 if (cr.Particle != null)
562 cr.Particle.MinOccurs = 0;
563 else if (cr.BaseTypeName != null &&
564 cr.BaseTypeName != QName.Empty &&
565 cr.BaseTypeName != QNameAnyType)
566 throw Error (cr, "Complex type content extension has a reference to an external component that is not supported.");
570 private void InferContent (Element el, string ns, bool isNew)
573 source.MoveToContent ();
574 switch (source.NodeType) {
575 case XmlNodeType.EndElement:
576 InferAsEmptyElement (el, ns, isNew);
578 case XmlNodeType.Element:
579 InferComplexContent (el, ns, isNew);
581 case XmlNodeType.Text:
582 case XmlNodeType.CDATA:
583 case XmlNodeType.SignificantWhitespace:
584 InferTextContent (el, isNew);
585 source.MoveToContent ();
586 if (source.NodeType == XmlNodeType.Element)
587 goto case XmlNodeType.Element;
589 case XmlNodeType.Whitespace:
590 InferContent (el, ns, isNew); // skip and retry
595 private void InferComplexContent (Element el, string ns,
598 ComplexType ct = ToComplexType (el);
599 ToComplexContentType (ct);
602 bool consumed = false;
605 switch (source.NodeType) {
606 case XmlNodeType.Element:
607 Sequence s = PopulateSequence (ct);
608 Choice c = s.Items.Count > 0 ?
609 s.Items [0] as Choice :
614 ProcessSequence (ct, s, ns,
618 source.MoveToContent ();
620 case XmlNodeType.Text:
621 case XmlNodeType.CDATA:
622 case XmlNodeType.SignificantWhitespace:
624 source.ReadString ();
625 source.MoveToContent ();
627 case XmlNodeType.EndElement:
629 case XmlNodeType.None:
630 throw new NotImplementedException ("Internal Error: Should not happen.");
635 private void InferTextContent (Element el, bool isNew)
637 string value = source.ReadString ();
638 if (el.SchemaType == null) {
639 if (el.SchemaTypeName == QName.Empty) {
640 // no type information -> infer type
650 switch (el.SchemaTypeName.Namespace) {
651 case XmlSchema.Namespace:
653 // existing primitive type
654 el.SchemaTypeName = InferMergedType (
655 value, el.SchemaTypeName);
658 ComplexType ct = schemas.GlobalTypes [
661 // If it is complex, then just set
662 // mixed='true' (type cannot be set.)
663 // If it is simple, then we cannot
664 // make sure that string value is
665 // valid. So just set as xs:string.
669 el.SchemaTypeName = QNameString;
675 SimpleType st = el.SchemaType as SimpleType;
677 // If simple, then (described above)
678 el.SchemaType = null;
679 el.SchemaTypeName = QNameString;
684 ComplexType ect = el.SchemaType as ComplexType;
686 SimpleModel sm = ect.ContentModel as SimpleModel;
694 SimpleExt se = sm.Content as SimpleExt;
696 se.BaseTypeName = InferMergedType (value,
698 SimpleRst sr = sm.Content as SimpleRst;
700 sr.BaseTypeName = InferMergedType (value,
706 private void MarkAsMixed (ComplexType ct)
708 ComplexModel cm = ct.ContentModel as ComplexModel;
719 private void ProcessLax (Choice c, string ns)
721 foreach (Particle p in c.Items) {
722 Element el = p as Element;
724 throw Error (c, String.Format ("Target schema item contains unacceptable particle {0}. Only element is allowed here."));
725 if (ElementMatches (el, ns)) {
726 InferElement (el, ns, false);
730 // append a new element particle to lax term.
731 Element nel = new Element ();
732 if (source.NamespaceURI == ns)
733 nel.Name = source.LocalName;
735 nel.RefName = new QName (source.LocalName,
736 source.NamespaceURI);
737 InferElement (nel, source.NamespaceURI, true);
741 private bool ElementMatches (Element el, string ns)
743 bool matches = false;
744 if (el.RefName != QName.Empty) {
745 if (el.RefName.Name == source.LocalName &&
746 el.RefName.Namespace ==
750 else if (el.Name == source.LocalName &&
751 ns == source.NamespaceURI)
756 private void ProcessSequence (ComplexType ct, Sequence s,
757 string ns, ref int position, ref bool consumed,
760 for (int i = 0; i < position; i++) {
761 Element iel = s.Items [i] as Element;
762 if (ElementMatches (iel, ns)) {
763 // Sequence element type violation
764 // might happen (might not, but we
765 // cannot backtrack here). So switch
766 // to sequence of choice* here.
767 ProcessLax (ToSequenceOfChoice (s), ns);
772 if (s.Items.Count <= position) {
773 QName name = new QName (source.LocalName,
774 source.NamespaceURI);
775 Element nel = CreateElement (name);
776 InferElement (nel, ns, true);
777 if (ns == name.Namespace)
780 Element re = new Element ();
787 Element el = s.Items [position] as Element;
789 throw Error (s, String.Format ("Target complex type content sequence has an unacceptable type of particle {0}", s.Items [position]));
790 bool matches = ElementMatches (el, ns);
793 el.MaxOccursString = "unbounded";
794 InferElement (el, source.NamespaceURI, false);
795 source.MoveToContent ();
796 switch (source.NodeType) {
797 case XmlNodeType.None:
798 if (source.NodeType ==
800 goto case XmlNodeType.Element;
801 else if (source.NodeType ==
802 XmlNodeType.EndElement)
803 goto case XmlNodeType.EndElement;
805 case XmlNodeType.Element:
806 ProcessSequence (ct, s, ns, ref position,
807 ref consumed, isNew);
809 case XmlNodeType.Text:
810 case XmlNodeType.CDATA:
811 case XmlNodeType.SignificantWhitespace:
813 source.ReadString ();
814 goto case XmlNodeType.None;
815 case XmlNodeType.Whitespace:
816 source.ReadString ();
817 goto case XmlNodeType.None;
818 case XmlNodeType.EndElement:
829 ProcessSequence (ct, s, ns,
830 ref position, ref consumed,
834 ProcessLax (ToSequenceOfChoice (s), ns);
838 // Note that it does not return the changed sequence.
839 private Choice ToSequenceOfChoice (Sequence s)
841 Choice c = new Choice ();
844 c.MaxOccursString = "unbounded";
845 foreach (Particle p in s.Items)
852 // It makes complexType not to have Simple content model.
853 private void ToComplexContentType (ComplexType type)
855 SimpleModel sm = type.ContentModel as SimpleModel;
859 SOMList atts = GetAttributes (type);
860 foreach (SOMObject o in atts)
861 type.Attributes.Add (o);
862 // FIXME: need to copy AnyAttribute.
863 // (though not considered right now)
864 type.ContentModel = null;
868 private Sequence PopulateSequence (ComplexType ct)
870 Particle p = PopulateParticle (ct);
871 Sequence s = p as Sequence;
875 throw Error (ct, String.Format ("Target complexType contains unacceptable type of particle {0}", p));
878 private Sequence CreateSequence ()
880 Sequence s = new Sequence ();
886 private Particle PopulateParticle (ComplexType ct)
888 if (ct.ContentModel == null) {
889 if (ct.Particle == null)
890 ct.Particle = CreateSequence ();
893 ComplexModel cm = ct.ContentModel as ComplexModel;
895 ComplexExt ce = cm.Content as ComplexExt;
897 if (ce.Particle == null)
898 ce.Particle = CreateSequence ();
901 ComplexRst cr = cm.Content as ComplexRst;
903 if (cr.Particle == null)
904 cr.Particle = CreateSequence ();
908 throw Error (ct, "Schema inference internal error. The complexType should have been converted to have a complex content.");
915 // primitive type inference.
916 // When running lax type inference, it just returns xs:string.
917 private QName InferSimpleType (string value)
919 if (laxTypeInference)
923 // 0 and 1 are not infered as byte unlike MS.XSDInfer
931 long dec = XmlConvert.ToInt64 (value);
932 if (byte.MinValue <= dec && dec <= byte.MaxValue)
933 return XmlSchemaType.GetBuiltInSimpleType (XmlTypeCode.UnsignedByte).QualifiedName;
934 if (sbyte.MinValue <= dec && dec <= sbyte.MaxValue)
935 return XmlSchemaType.GetBuiltInSimpleType (XmlTypeCode.Byte).QualifiedName;
936 if (ushort.MinValue <= dec && dec <= ushort.MaxValue)
937 return XmlSchemaType.GetBuiltInSimpleType (XmlTypeCode.UnsignedShort).QualifiedName;
938 if (short.MinValue <= dec && dec <= short.MaxValue)
939 return XmlSchemaType.GetBuiltInSimpleType (XmlTypeCode.Short).QualifiedName;
940 if (uint.MinValue <= dec && dec <= uint.MaxValue)
941 return XmlSchemaType.GetBuiltInSimpleType (XmlTypeCode.UnsignedInt).QualifiedName;
942 if (int.MinValue <= dec && dec <= int.MaxValue)
943 return XmlSchemaType.GetBuiltInSimpleType (XmlTypeCode.Int).QualifiedName;
944 return XmlSchemaType.GetBuiltInSimpleType (XmlTypeCode.Long).QualifiedName;
945 } catch (Exception) {
948 XmlConvert.ToUInt64 (value);
949 return XmlSchemaType.GetBuiltInSimpleType (XmlTypeCode.UnsignedLong).QualifiedName;
950 } catch (Exception) {
953 XmlConvert.ToDecimal (value);
954 return XmlSchemaType.GetBuiltInSimpleType (XmlTypeCode.Decimal).QualifiedName;
955 } catch (Exception) {
958 double dbl = XmlConvert.ToDouble (value);
959 if (float.MinValue <= dbl &&
960 dbl <= float.MaxValue)
961 return XmlSchemaType.GetBuiltInSimpleType (XmlTypeCode.Float).QualifiedName;
963 return XmlSchemaType.GetBuiltInSimpleType (XmlTypeCode.Double).QualifiedName;
964 } catch (Exception) {
967 // FIXME: also try DateTimeSerializationMode
969 XmlConvert.ToDateTime (value);
970 return XmlSchemaType.GetBuiltInSimpleType (XmlTypeCode.DateTime).QualifiedName;
971 } catch (Exception) {
974 XmlConvert.ToTimeSpan (value);
975 return XmlSchemaType.GetBuiltInSimpleType (XmlTypeCode.Duration).QualifiedName;
976 } catch (Exception) {
987 private Element GetGlobalElement (QName name)
989 Element el = newElements [name] as Element;
991 el = schemas.GlobalElements [name] as Element;
995 private Attr GetGlobalAttribute (QName name)
997 Attr a = newElements [name] as Attr;
999 a = schemas.GlobalAttributes [name] as Attr;
1003 private Element CreateElement (QName name)
1005 Element el = new Element ();
1006 el.Name = name.Name;
1010 private Element CreateGlobalElement (QName name)
1012 Element el = CreateElement (name);
1013 XmlSchema schema = PopulateSchema (name.Namespace);
1014 schema.Items.Add (el);
1015 newElements.Add (name, el);
1019 private Attr CreateGlobalAttribute (QName name)
1021 Attr attr = new Attr ();
1022 XmlSchema schema = PopulateSchema (name.Namespace);
1023 attr.Name = name.Name;
1024 schema.Items.Add (attr);
1025 newAttributes.Add (name, attr);
1029 // Note that the return value never assures that all the
1030 // components in the parameter ns must reside in it.
1031 private XmlSchema PopulateSchema (string ns)
1033 ICollection list = schemas.Schemas (ns);
1034 if (list.Count > 0) {
1035 IEnumerator e = list.GetEnumerator ();
1037 return (XmlSchema) e.Current;
1039 XmlSchema s = new XmlSchema ();
1040 if (ns != null && ns.Length > 0)
1041 s.TargetNamespace = ns;
1042 s.ElementFormDefault = Form.Qualified;
1043 s.AttributeFormDefault = Form.Unqualified;
1048 private XmlSchemaInferenceException Error (
1049 XmlSchemaObject sourceObj,
1052 // This override is mainly for schema component error.
1053 return Error (sourceObj, false, message);
1056 private XmlSchemaInferenceException Error (
1057 XmlSchemaObject sourceObj,
1061 string msg = String.Concat (
1064 String.Format (". Related schema component is {0}",
1065 sourceObj.SourceUri,
1066 sourceObj.LineNumber,
1067 sourceObj.LinePosition) :
1070 String.Format (". {0}", source.BaseURI) :
1073 IXmlLineInfo li = source as IXmlLineInfo;
1074 if (useReader && li != null)
1075 return new XmlSchemaInferenceException (
1076 msg, null, li.LineNumber,
1079 return new XmlSchemaInferenceException (msg);