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 public class XmlSchemaInference
70 public enum InferenceOption {
75 InferenceOption occurrence = InferenceOption.Rstricted;
76 InferenceOption typeInference = InferenceOption.Rstricted;
78 public XmlSchemaInference ()
82 public InferenceOption Occurrence {
83 get { return occurrence; }
84 set { occurrence = value; }
87 public InferenceOption TypeInference {
88 get { return TypeInference; }
89 set { typeInference = value; }
92 public XmlSchemaSet InferSchema (XmlReader xmlReader)
94 return InferSchema (xmlReader, new XmlSchemaSet ());
97 public XmlSchemaSet InferSchema (XmlReader xmlReader, XmlSchemaSet schemas)
99 return XsdInference.Process (xmlReader, schemas,
100 occurrence == InferenceOption.Relaxed,
101 typeInference == InferenceOption.Relaxed);
107 public static XmlSchemaSet Process (XmlReader xmlReader, XmlSchemaSet schemas, bool laxOccurence, bool laxTypeInference)
109 XsdInference impl = new XsdInference (xmlReader,
110 schemas, laxOccurence, laxTypeInference);
115 public const string NamespaceXml = "http://www.w3.org/XML/1998/namespace";
117 public const string NamespaceXmlns = "http://www.w3.org/2000/xmlns/";
119 public const string XdtNamespace = "http://www.w3.org/2003/11/xpath-datatypes";
121 static readonly QName QNameString = new QName ("string",
122 XmlSchema.Namespace);
124 static readonly QName QNameBoolean = new QName ("boolean",
125 XmlSchema.Namespace);
127 static readonly QName QNameAnyType = new QName ("anyType",
128 XmlSchema.Namespace);
131 XmlSchemaSet schemas;
133 bool laxTypeInference;
135 Hashtable newElements = new Hashtable ();
136 Hashtable newAttributes = new Hashtable ();
138 private XsdInference (XmlReader xmlReader, XmlSchemaSet schemas, bool laxOccurence, bool laxTypeInference)
140 this.source = xmlReader;
141 this.schemas = schemas;
142 this.laxOccurence = laxOccurence;
143 this.laxTypeInference = laxTypeInference;
148 // XmlSchemaSet need to be compiled.
151 // move to top-level element
152 source.MoveToContent ();
153 int depth = source.Depth;
154 if (source.NodeType != XmlNodeType.Element)
155 throw new ArgumentException ("Argument XmlReader content is expected to be an element.");
157 QName qname = new QName (source.LocalName,
158 source.NamespaceURI);
159 Element el = GetGlobalElement (qname);
161 el = CreateGlobalElement (qname);
162 InferElement (el, qname.Namespace, true);
165 InferElement (el, qname.Namespace, false);
168 private void IncludeXmlAttributes ()
170 if (schemas.Schemas (NamespaceXml).Count == 0)
171 // FIXME: do it from resources.
172 schemas.Add (NamespaceXml, "http://www.w3.org/2001/xml.xsd");
175 private void InferElement (Element el, string ns, bool isNew)
177 // Quick check for reference to another definition
178 // (i.e. element ref='...' that should be redirected)
179 if (el.RefName != QName.Empty) {
180 Element body = GetGlobalElement (el.RefName);
182 body = CreateElement (el.RefName);
183 InferElement (body, ns, true);
186 InferElement (body, ns, isNew);
191 if (source.MoveToFirstAttribute ()) {
192 InferAttributes (el, ns, isNew);
193 source.MoveToElement ();
197 if (source.IsEmptyElement) {
198 InferAsEmptyElement (el, ns, isNew);
200 source.MoveToContent ();
203 InferContent (el, ns, isNew);
204 source.ReadEndElement ();
206 if (el.SchemaType == null &&
207 el.SchemaTypeName == QName.Empty)
208 el.SchemaTypeName = QNameString;
211 #region Attribute Inference
213 private Hashtable CollectAttrTable (SOMList attList)
215 // get attribute definition table.
216 Hashtable table = new Hashtable ();
217 foreach (XmlSchemaObject obj in attList) {
218 Attr attr = obj as Attr;
220 throw Error (obj, String.Format ("Attribute inference only supports direct attribute definition. {0} is not supported.", obj.GetType ()));
221 if (attr.RefName != QName.Empty)
222 table.Add (attr.RefName, attr);
224 table.Add (new QName (attr.Name, ""),
230 private void InferAttributes (Element el, string ns, bool isNew)
232 // Now this element is going to have complexType.
233 // It currently not, then we have to replace it.
234 ComplexType ct = null;
235 SOMList attList = null;
236 Hashtable table = null;
239 switch (source.NamespaceURI) {
241 if (schemas.Schemas (
242 NamespaceXml) .Count == 0)
243 IncludeXmlAttributes ();
245 case XmlSchema.InstanceNamespace:
246 if (source.LocalName == "nil")
247 el.IsNillable = true;
248 // all other xsi:* atts are ignored
254 ct = ToComplexType (el);
255 attList = GetAttributes (ct);
256 table = CollectAttrTable (attList);
258 QName attrName = new QName (
259 source.LocalName, source.NamespaceURI);
260 Attr attr = table [attrName] as Attr;
262 attList.Add (InferNewAttribute (
265 table.Remove (attrName);
266 if (attr.RefName != null &&
267 attr.RefName != QName.Empty)
268 continue; // just a reference
269 InferMergedAttribute (attr);
271 } while (source.MoveToNextAttribute ());
273 // mark all attr definitions that did not appear
276 foreach (Attr attr in table.Values)
277 attr.Use = Use.Optional;
280 private XmlSchemaAttribute InferNewAttribute (
281 QName attrName, bool isNewTypeDefinition)
284 bool mergedRequired = false;
285 if (attrName.Namespace.Length > 0) {
286 // global attribute; might be already defined.
287 attr = GetGlobalAttribute (attrName) as Attr;
289 attr = CreateGlobalAttribute (attrName);
290 attr.SchemaTypeName =
291 InferSimpleType (source.Value);
293 InferMergedAttribute (attr);
295 attr.Use == Use.Required;
298 attr.RefName = attrName;
302 attr.Name = attrName.Name;
303 attr.SchemaTypeName =
304 InferSimpleType (source.Value);
307 (isNewTypeDefinition || mergedRequired))
308 attr.Use = Use.Required;
310 attr.Use = Use.Optional;
315 // validate string value agains attr and
316 // if invalid, then relax the type.
317 private void InferMergedAttribute (Attr attr)
319 attr.SchemaTypeName = InferMergedType (source.Value,
320 attr.SchemaTypeName);
321 attr.SchemaType = null;
324 private QName InferMergedType (string value, QName typeName)
326 // examine value against specified type and
327 // if unacceptable, then return a relaxed type.
329 SimpleType st = XmlSchemaType.GetBuiltInSimpleType (
331 if (st == null) // non-primitive type => see above.
334 st.Datatype.ParseValue (value,
336 source as IXmlNamespaceResolver);
337 // the string value was value
340 // The types were incompatible.
341 // FIXME: find the base common type
346 private SOMList GetAttributes (ComplexType ct)
348 if (ct.ContentModel == null)
349 return ct.Attributes;
351 SimpleModel sc = ct.ContentModel as SimpleModel;
353 SimpleExt sce = sc.Content as SimpleExt;
355 return sce.Attributes;
356 SimpleRst scr = sc.Content as SimpleRst;
358 return scr.Attributes;
360 throw Error (sc, "Invalid simple content model.");
362 ComplexModel cc = ct.ContentModel as ComplexModel;
364 ComplexExt cce = cc.Content as ComplexExt;
366 return cce.Attributes;
367 ComplexRst ccr = cc.Content as ComplexRst;
369 return ccr.Attributes;
371 throw Error (cc, "Invalid simple content model.");
373 throw Error (cc, "Invalid complexType. Should not happen.");
376 private ComplexType ToComplexType (Element el)
378 QName name = el.SchemaTypeName;
379 XmlSchemaType type = el.SchemaType;
381 // 1. element type is complex.
382 ComplexType ct = type as ComplexType;
386 // 2. reference to global complexType.
387 XmlSchemaType globalType = schemas.GlobalTypes [name]
389 ct = globalType as ComplexType;
393 ct = new ComplexType ();
395 el.SchemaTypeName = QName.Empty;
397 // 3. base type name is xs:anyType or no specification.
398 // <xs:complexType />
399 if (name == QNameAnyType)
401 else if (type == null && name == QName.Empty)
404 SimpleModel sc = new SimpleModel ();
405 ct.ContentModel = sc;
407 // 4. type is simpleType
408 // -> extension of existing simple type.
409 SimpleType st = type as SimpleType;
411 SimpleRst scr = new SimpleRst ();
417 SimpleExt sce = new SimpleExt ();
420 // 5. type name points to primitive type
421 // -> simple extension of a primitive type
422 st = XmlSchemaType.GetBuiltInSimpleType (name);
424 sce.BaseTypeName = name;
428 // 6. type name points to global simpleType.
429 st = globalType as SimpleType;
431 sce.BaseTypeName = name;
435 throw Error (el, "Unexpected schema component that contains simpleTypeName that could not be resolved.");
442 private void InferAsEmptyElement (Element el, string ns,
445 ComplexType ct = el.SchemaType as ComplexType;
448 ct.ContentModel as SimpleModel;
450 ToEmptiableSimpleContent (sm, isNew);
454 ComplexModel cm = ct.ContentModel
457 ToEmptiableComplexContent (cm, isNew);
461 if (ct.Particle != null)
462 ct.Particle.MinOccurs = 0;
465 SimpleType st = el.SchemaType as SimpleType;
467 st = MakeBaseTypeAsEmptiable (st);
468 switch (st.QualifiedName.Namespace) {
469 case XmlSchema.Namespace:
471 el.SchemaTypeName = st.QualifiedName;
480 private SimpleType MakeBaseTypeAsEmptiable (SimpleType st)
482 switch (st.QualifiedName.Namespace) {
483 case XmlSchema.Namespace:
485 // If a primitive type
486 return XmlSchemaType.GetBuiltInSimpleType (
489 SimpleTypeRst str = st.Content as SimpleTypeRst;
492 foreach (SchemaFacet f in str.Facets) {
493 if (f is LengthFacet ||
494 f is MinLengthFacet) {
496 al = new ArrayList ();
500 foreach (SchemaFacet f in al)
501 str.Facets.Remove (f);
502 if (str.BaseType != null)
504 MakeBaseTypeAsEmptiable (st);
506 // It might have a reference to an
507 // external simple type, but there is
508 // no assurance that any of those
509 // external types allow an empty
510 // string. So just set base type as
512 str.BaseTypeName = QNameString;
513 } // union/list can have empty string value.
518 private void ToEmptiableSimpleContent (
519 SimpleModel sm, bool isNew)
521 SimpleExt se = sm.Content as SimpleExt;
523 se.BaseTypeName = QNameString;
525 SimpleRst sr = sm.Content
528 throw Error (sm, "Invalid simple content model was passed.");
529 sr.BaseTypeName = QNameString;
534 private void ToEmptiableComplexContent (
535 ComplexModel cm, bool isNew)
537 ComplexExt ce = cm.Content
540 if (ce.Particle != null)
541 ce.Particle.MinOccurs = 0;
542 else if (ce.BaseTypeName != null &&
543 ce.BaseTypeName != QName.Empty &&
544 ce.BaseTypeName != QNameAnyType)
545 throw Error (ce, "Complex type content extension has a reference to an external component that is not supported.");
548 ComplexRst cr = cm.Content
551 throw Error (cm, "Invalid complex content model was passed.");
552 if (cr.Particle != null)
553 cr.Particle.MinOccurs = 0;
554 else if (cr.BaseTypeName != null &&
555 cr.BaseTypeName != QName.Empty &&
556 cr.BaseTypeName != QNameAnyType)
557 throw Error (cr, "Complex type content extension has a reference to an external component that is not supported.");
561 private void InferContent (Element el, string ns, bool isNew)
564 source.MoveToContent ();
565 switch (source.NodeType) {
566 case XmlNodeType.EndElement:
567 InferAsEmptyElement (el, ns, isNew);
569 case XmlNodeType.Element:
570 InferComplexContent (el, ns, isNew);
572 case XmlNodeType.Text:
573 case XmlNodeType.CDATA:
574 case XmlNodeType.SignificantWhitespace:
575 InferTextContent (el, isNew);
576 source.MoveToContent ();
577 if (source.NodeType == XmlNodeType.Element)
578 goto case XmlNodeType.Element;
580 case XmlNodeType.Whitespace:
581 InferContent (el, ns, isNew); // skip and retry
586 private void InferComplexContent (Element el, string ns,
589 ComplexType ct = ToComplexType (el);
590 ToComplexContentType (ct);
593 bool consumed = false;
596 switch (source.NodeType) {
597 case XmlNodeType.Element:
598 Sequence s = PopulateSequence (ct);
599 Choice c = s.Items.Count > 0 ?
600 s.Items [0] as Choice :
605 ProcessSequence (ct, s, ns,
609 source.MoveToContent ();
611 case XmlNodeType.Text:
612 case XmlNodeType.CDATA:
613 case XmlNodeType.SignificantWhitespace:
615 source.ReadString ();
616 source.MoveToContent ();
618 case XmlNodeType.EndElement:
620 case XmlNodeType.None:
621 throw new NotImplementedException ("Internal Error: Should not happen.");
626 private void InferTextContent (Element el, bool isNew)
628 string value = source.ReadString ();
629 if (el.SchemaType == null) {
630 if (el.SchemaTypeName == QName.Empty) {
631 // no type information -> infer type
641 switch (el.SchemaTypeName.Namespace) {
642 case XmlSchema.Namespace:
644 // existing primitive type
645 el.SchemaTypeName = InferMergedType (
646 value, el.SchemaTypeName);
649 ComplexType ct = schemas.GlobalTypes [
652 // If it is complex, then just set
653 // mixed='true' (type cannot be set.)
654 // If it is simple, then we cannot
655 // make sure that string value is
656 // valid. So just set as xs:string.
660 el.SchemaTypeName = QNameString;
666 SimpleType st = el.SchemaType as SimpleType;
668 // If simple, then (described above)
669 el.SchemaType = null;
670 el.SchemaTypeName = QNameString;
675 ComplexType ect = el.SchemaType as ComplexType;
677 SimpleModel sm = ect.ContentModel as SimpleModel;
685 SimpleExt se = sm.Content as SimpleExt;
687 se.BaseTypeName = InferMergedType (value,
689 SimpleRst sr = sm.Content as SimpleRst;
691 sr.BaseTypeName = InferMergedType (value,
697 private void MarkAsMixed (ComplexType ct)
699 ComplexModel cm = ct.ContentModel as ComplexModel;
710 private void ProcessLax (Choice c, string ns)
712 foreach (Particle p in c.Items) {
713 Element el = p as Element;
715 throw Error (c, String.Format ("Target schema item contains unacceptable particle {0}. Only element is allowed here."));
716 if (ElementMatches (el, ns)) {
717 InferElement (el, ns, false);
721 // append a new element particle to lax term.
722 Element nel = new Element ();
723 if (source.NamespaceURI == ns)
724 nel.Name = source.LocalName;
726 nel.RefName = new QName (source.LocalName,
727 source.NamespaceURI);
728 InferElement (nel, source.NamespaceURI, true);
732 private bool ElementMatches (Element el, string ns)
734 bool matches = false;
735 if (el.RefName != QName.Empty) {
736 if (el.RefName.Name == source.LocalName &&
737 el.RefName.Namespace ==
741 else if (el.Name == source.LocalName &&
742 ns == source.NamespaceURI)
747 private void ProcessSequence (ComplexType ct, Sequence s,
748 string ns, ref int position, ref bool consumed,
751 for (int i = 0; i < position; i++) {
752 Element iel = s.Items [i] as Element;
753 if (ElementMatches (iel, ns)) {
754 // Sequence element type violation
755 // might happen (might not, but we
756 // cannot backtrack here). So switch
757 // to sequence of choice* here.
758 ProcessLax (ToSequenceOfChoice (s), ns);
763 if (s.Items.Count <= position) {
764 QName name = new QName (source.LocalName,
765 source.NamespaceURI);
766 Element nel = CreateElement (name);
767 InferElement (nel, ns, true);
768 if (ns == name.Namespace)
771 Element re = new Element ();
778 Element el = s.Items [position] as Element;
780 throw Error (s, String.Format ("Target complex type content sequence has an unacceptable type of particle {0}", s.Items [position]));
781 bool matches = ElementMatches (el, ns);
784 el.MaxOccursString = "unbounded";
785 InferElement (el, source.NamespaceURI, false);
786 source.MoveToContent ();
787 switch (source.NodeType) {
788 case XmlNodeType.None:
789 if (source.NodeType ==
791 goto case XmlNodeType.Element;
792 else if (source.NodeType ==
793 XmlNodeType.EndElement)
794 goto case XmlNodeType.EndElement;
796 case XmlNodeType.Element:
797 ProcessSequence (ct, s, ns, ref position,
798 ref consumed, isNew);
800 case XmlNodeType.Text:
801 case XmlNodeType.CDATA:
802 case XmlNodeType.SignificantWhitespace:
804 source.ReadString ();
805 goto case XmlNodeType.None;
806 case XmlNodeType.Whitespace:
807 source.ReadString ();
808 goto case XmlNodeType.None;
809 case XmlNodeType.EndElement:
820 ProcessSequence (ct, s, ns,
821 ref position, ref consumed,
825 ProcessLax (ToSequenceOfChoice (s), ns);
829 // Note that it does not return the changed sequence.
830 private Choice ToSequenceOfChoice (Sequence s)
832 Choice c = new Choice ();
835 c.MaxOccursString = "unbounded";
836 foreach (Particle p in s.Items)
843 // It makes complexType not to have Simple content model.
844 private void ToComplexContentType (ComplexType type)
846 SimpleModel sm = type.ContentModel as SimpleModel;
850 SOMList atts = GetAttributes (type);
851 foreach (SOMObject o in atts)
852 type.Attributes.Add (o);
853 // FIXME: need to copy AnyAttribute.
854 // (though not considered right now)
855 type.ContentModel = null;
859 private Sequence PopulateSequence (ComplexType ct)
861 Particle p = PopulateParticle (ct);
862 Sequence s = p as Sequence;
866 throw Error (ct, String.Format ("Target complexType contains unacceptable type of particle {0}", p));
869 private Sequence CreateSequence ()
871 Sequence s = new Sequence ();
877 private Particle PopulateParticle (ComplexType ct)
879 if (ct.ContentModel == null) {
880 if (ct.Particle == null)
881 ct.Particle = CreateSequence ();
884 ComplexModel cm = ct.ContentModel as ComplexModel;
886 ComplexExt ce = cm.Content as ComplexExt;
888 if (ce.Particle == null)
889 ce.Particle = CreateSequence ();
892 ComplexRst cr = cm.Content as ComplexRst;
894 if (cr.Particle == null)
895 cr.Particle = CreateSequence ();
899 throw Error (ct, "Schema inference internal error. The complexType should have been converted to have a complex content.");
906 // primitive type inference.
907 // When running lax type inference, it just returns xs:string.
908 private QName InferSimpleType (string value)
910 if (laxTypeInference)
914 // 0 and 1 are not infered as byte unlike MS.XSDInfer
922 long dec = XmlConvert.ToInt64 (value);
923 if (byte.MinValue <= dec && dec <= byte.MaxValue)
924 return XmlSchemaType.GetBuiltInSimpleType (XmlTypeCode.UnsignedByte).QualifiedName;
925 if (sbyte.MinValue <= dec && dec <= sbyte.MaxValue)
926 return XmlSchemaType.GetBuiltInSimpleType (XmlTypeCode.Byte).QualifiedName;
927 if (ushort.MinValue <= dec && dec <= ushort.MaxValue)
928 return XmlSchemaType.GetBuiltInSimpleType (XmlTypeCode.UnsignedShort).QualifiedName;
929 if (short.MinValue <= dec && dec <= short.MaxValue)
930 return XmlSchemaType.GetBuiltInSimpleType (XmlTypeCode.Short).QualifiedName;
931 if (uint.MinValue <= dec && dec <= uint.MaxValue)
932 return XmlSchemaType.GetBuiltInSimpleType (XmlTypeCode.UnsignedInt).QualifiedName;
933 if (int.MinValue <= dec && dec <= int.MaxValue)
934 return XmlSchemaType.GetBuiltInSimpleType (XmlTypeCode.Int).QualifiedName;
935 return XmlSchemaType.GetBuiltInSimpleType (XmlTypeCode.Long).QualifiedName;
936 } catch (Exception) {
939 XmlConvert.ToUInt64 (value);
940 return XmlSchemaType.GetBuiltInSimpleType (XmlTypeCode.UnsignedLong).QualifiedName;
941 } catch (Exception) {
944 XmlConvert.ToDecimal (value);
945 return XmlSchemaType.GetBuiltInSimpleType (XmlTypeCode.Decimal).QualifiedName;
946 } catch (Exception) {
949 double dbl = XmlConvert.ToDouble (value);
950 if (float.MinValue <= dbl && dbl <= float.MaxValue)
951 return XmlSchemaType.GetBuiltInSimpleType (XmlTypeCode.Float).QualifiedName;
953 return XmlSchemaType.GetBuiltInSimpleType (XmlTypeCode.Double).QualifiedName;
954 } catch (Exception) {
957 // FIXME: also try DateTimeSerializationMode
959 XmlConvert.ToDateTime (value);
960 return XmlSchemaType.GetBuiltInSimpleType (XmlTypeCode.DateTime).QualifiedName;
961 } catch (Exception) {
964 XmlConvert.ToTimeSpan (value);
965 return XmlSchemaType.GetBuiltInSimpleType (XmlTypeCode.Duration).QualifiedName;
966 } catch (Exception) {
977 private Element GetGlobalElement (QName name)
979 Element el = newElements [name] as Element;
981 el = schemas.GlobalElements [name] as Element;
985 private Attr GetGlobalAttribute (QName name)
987 Attr a = newElements [name] as Attr;
989 a = schemas.GlobalAttributes [name] as Attr;
993 private Element CreateElement (QName name)
995 Element el = new Element ();
1000 private Element CreateGlobalElement (QName name)
1002 Element el = CreateElement (name);
1003 XmlSchema schema = PopulateSchema (name.Namespace);
1004 schema.Items.Add (el);
1005 newElements.Add (name, el);
1009 private Attr CreateGlobalAttribute (QName name)
1011 Attr attr = new Attr ();
1012 XmlSchema schema = PopulateSchema (name.Namespace);
1013 attr.Name = name.Name;
1014 schema.Items.Add (attr);
1015 newAttributes.Add (name, attr);
1019 // Note that the return value never assures that all the
1020 // components in the parameter ns must reside in it.
1021 private XmlSchema PopulateSchema (string ns)
1023 ICollection list = schemas.Schemas (ns);
1024 if (list.Count > 0) {
1025 IEnumerator e = list.GetEnumerator ();
1027 return (XmlSchema) e.Current;
1029 XmlSchema s = new XmlSchema ();
1030 if (ns != null && ns.Length > 0)
1031 s.TargetNamespace = ns;
1032 s.ElementFormDefault = Form.Qualified;
1033 s.AttributeFormDefault = Form.Unqualified;
1038 private XmlSchemaInferenceException Error (
1039 XmlSchemaObject sourceObj,
1042 // This override is mainly for schema component error.
1043 return Error (sourceObj, false, message);
1046 private XmlSchemaInferenceException Error (
1047 XmlSchemaObject sourceObj,
1051 string msg = String.Concat (
1054 String.Format (". Related schema component is {0}",
1055 sourceObj.SourceUri,
1056 sourceObj.LineNumber,
1057 sourceObj.LinePosition) :
1060 String.Format (". {0}", source.BaseURI) :
1063 IXmlLineInfo li = source as IXmlLineInfo;
1064 if (useReader && li != null)
1065 return new XmlSchemaInferenceException (
1066 msg, null, li.LineNumber,
1069 return new XmlSchemaInferenceException (msg);