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 =
121 "http://www.w3.org/XML/1998/namespace";
123 public const string NamespaceXmlns =
124 "http://www.w3.org/2000/xmlns/";
126 public const string XdtNamespace =
127 "http://www.w3.org/2003/11/xpath-datatypes";
129 static readonly QName QNameString = new QName (
130 "string", XmlSchema.Namespace);
132 static readonly QName QNameBoolean = new QName (
133 "boolean", XmlSchema.Namespace);
135 static readonly QName QNameAnyType = new QName (
136 "anyType", XmlSchema.Namespace);
138 static readonly QName QNameByte = new QName (
139 "byte", XmlSchema.Namespace);
141 static readonly QName QNameUByte = new QName (
142 "unsignedByte", XmlSchema.Namespace);
144 static readonly QName QNameShort = new QName (
145 "short", XmlSchema.Namespace);
147 static readonly QName QNameUShort = new QName (
148 "unsignedShort", XmlSchema.Namespace);
150 static readonly QName QNameInt = new QName (
151 "int", XmlSchema.Namespace);
153 static readonly QName QNameUInt = new QName (
154 "unsignedInt", XmlSchema.Namespace);
156 static readonly QName QNameLong = new QName (
157 "long", XmlSchema.Namespace);
159 static readonly QName QNameULong = new QName (
160 "unsignedLong", XmlSchema.Namespace);
162 static readonly QName QNameDecimal = new QName (
163 "decimal", XmlSchema.Namespace);
165 static readonly QName QNameUDecimal = new QName (
166 "unsignedDecimal", XmlSchema.Namespace);
168 static readonly QName QNameDouble = new QName (
169 "double", XmlSchema.Namespace);
171 static readonly QName QNameFloat = new QName (
172 "float", XmlSchema.Namespace);
174 static readonly QName QNameDateTime = new QName (
175 "dateTime", XmlSchema.Namespace);
177 static readonly QName QNameDuration = new QName (
178 "duration", XmlSchema.Namespace);
181 XmlSchemaSet schemas;
183 bool laxTypeInference;
185 Hashtable newElements = new Hashtable ();
186 Hashtable newAttributes = new Hashtable ();
188 private XsdInference (XmlReader xmlReader,
189 XmlSchemaSet schemas,
191 bool laxTypeInference)
193 this.source = xmlReader;
194 this.schemas = schemas;
195 this.laxOccurence = laxOccurence;
196 this.laxTypeInference = laxTypeInference;
201 // XmlSchemaSet need to be compiled.
204 // move to top-level element
205 source.MoveToContent ();
206 int depth = source.Depth;
207 if (source.NodeType != XmlNodeType.Element)
208 throw new ArgumentException ("Argument XmlReader content is expected to be an element.");
210 QName qname = new QName (source.LocalName,
211 source.NamespaceURI);
212 Element el = GetGlobalElement (qname);
214 el = CreateGlobalElement (qname);
215 InferElement (el, qname.Namespace, true);
218 InferElement (el, qname.Namespace, false);
220 // finally compile again.
224 private void IncludeXmlAttributes ()
226 if (schemas.Schemas (NamespaceXml).Count == 0)
227 // FIXME: do it from resources.
228 schemas.Add (NamespaceXml,
229 "http://www.w3.org/2001/xml.xsd");
232 private void InferElement (Element el, string ns, bool isNew)
234 // Quick check for reference to another definition
235 // (i.e. element ref='...' that should be redirected)
236 if (el.RefName != QName.Empty) {
237 Element body = GetGlobalElement (el.RefName);
239 body = CreateElement (el.RefName);
240 InferElement (body, ns, true);
243 InferElement (body, ns, isNew);
248 if (source.MoveToFirstAttribute ()) {
249 InferAttributes (el, ns, isNew);
250 source.MoveToElement ();
254 if (source.IsEmptyElement) {
255 InferAsEmptyElement (el, ns, isNew);
257 source.MoveToContent ();
260 InferContent (el, ns, isNew);
261 source.ReadEndElement ();
263 if (el.SchemaType == null &&
264 el.SchemaTypeName == QName.Empty)
265 el.SchemaTypeName = QNameString;
268 #region Attribute Inference
270 private Hashtable CollectAttrTable (SOMList attList)
272 // get attribute definition table.
273 Hashtable table = new Hashtable ();
274 foreach (XmlSchemaObject obj in attList) {
275 Attr attr = obj as Attr;
277 throw Error (obj, String.Format ("Attribute inference only supports direct attribute definition. {0} is not supported.", obj.GetType ()));
278 if (attr.RefName != QName.Empty)
279 table.Add (attr.RefName, attr);
281 table.Add (new QName (attr.Name, ""),
287 private void InferAttributes (Element el, string ns, bool isNew)
289 // Now this element is going to have complexType.
290 // It currently not, then we have to replace it.
291 ComplexType ct = null;
292 SOMList attList = null;
293 Hashtable table = null;
296 switch (source.NamespaceURI) {
298 if (schemas.Schemas (
299 NamespaceXml) .Count == 0)
300 IncludeXmlAttributes ();
302 case XmlSchema.InstanceNamespace:
303 if (source.LocalName == "nil")
304 el.IsNillable = true;
305 // all other xsi:* atts are ignored
311 ct = ToComplexType (el);
312 attList = GetAttributes (ct);
313 table = CollectAttrTable (attList);
315 QName attrName = new QName (
316 source.LocalName, source.NamespaceURI);
317 Attr attr = table [attrName] as Attr;
319 attList.Add (InferNewAttribute (
322 table.Remove (attrName);
323 if (attr.RefName != null &&
324 attr.RefName != QName.Empty)
325 continue; // just a reference
326 InferMergedAttribute (attr);
328 } while (source.MoveToNextAttribute ());
330 // mark all attr definitions that did not appear
333 foreach (Attr attr in table.Values)
334 attr.Use = Use.Optional;
337 private XmlSchemaAttribute InferNewAttribute (
338 QName attrName, bool isNewTypeDefinition)
341 bool mergedRequired = false;
342 if (attrName.Namespace.Length > 0) {
343 // global attribute; might be already defined.
344 attr = GetGlobalAttribute (attrName) as Attr;
346 attr = CreateGlobalAttribute (attrName);
347 attr.SchemaTypeName =
348 InferSimpleType (source.Value);
350 InferMergedAttribute (attr);
352 attr.Use == Use.Required;
355 attr.RefName = attrName;
359 attr.Name = attrName.Name;
360 attr.SchemaTypeName =
361 InferSimpleType (source.Value);
364 (isNewTypeDefinition || mergedRequired))
365 attr.Use = Use.Required;
367 attr.Use = Use.Optional;
372 // validate string value agains attr and
373 // if invalid, then relax the type.
374 private void InferMergedAttribute (Attr attr)
376 attr.SchemaTypeName = InferMergedType (source.Value,
377 attr.SchemaTypeName);
378 attr.SchemaType = null;
381 private QName InferMergedType (string value, QName typeName)
383 // examine value against specified type and
384 // if unacceptable, then return a relaxed type.
386 SimpleType st = XmlSchemaType.GetBuiltInSimpleType (
388 if (st == null) // non-primitive type => see above.
392 st.Datatype.ParseValue (value,
394 source as IXmlNamespaceResolver);
397 st = st.BaseXmlSchemaType as XmlSchemaSimpleType;
398 typeName = st != null ? st.QualifiedName : QName.Empty;
400 } while (typeName != QName.Empty);
404 private SOMList GetAttributes (ComplexType ct)
406 if (ct.ContentModel == null)
407 return ct.Attributes;
409 SimpleModel sc = ct.ContentModel as SimpleModel;
411 SimpleExt sce = sc.Content as SimpleExt;
413 return sce.Attributes;
414 SimpleRst scr = sc.Content as SimpleRst;
416 return scr.Attributes;
418 throw Error (sc, "Invalid simple content model.");
420 ComplexModel cc = ct.ContentModel as ComplexModel;
422 ComplexExt cce = cc.Content as ComplexExt;
424 return cce.Attributes;
425 ComplexRst ccr = cc.Content as ComplexRst;
427 return ccr.Attributes;
429 throw Error (cc, "Invalid simple content model.");
431 throw Error (cc, "Invalid complexType. Should not happen.");
434 private ComplexType ToComplexType (Element el)
436 QName name = el.SchemaTypeName;
437 XmlSchemaType type = el.SchemaType;
439 // 1. element type is complex.
440 ComplexType ct = type as ComplexType;
444 // 2. reference to global complexType.
445 XmlSchemaType globalType = schemas.GlobalTypes [name]
447 ct = globalType as ComplexType;
451 ct = new ComplexType ();
453 el.SchemaTypeName = QName.Empty;
455 // 3. base type name is xs:anyType or no specification.
456 // <xs:complexType />
457 if (name == QNameAnyType)
459 else if (type == null && name == QName.Empty)
462 SimpleModel sc = new SimpleModel ();
463 ct.ContentModel = sc;
465 // 4. type is simpleType
466 // -> extension of existing simple type.
467 SimpleType st = type as SimpleType;
469 SimpleRst scr = new SimpleRst ();
475 SimpleExt sce = new SimpleExt ();
478 // 5. type name points to primitive type
479 // -> simple extension of a primitive type
480 st = XmlSchemaType.GetBuiltInSimpleType (name);
482 sce.BaseTypeName = name;
486 // 6. type name points to global simpleType.
487 st = globalType as SimpleType;
489 sce.BaseTypeName = name;
493 throw Error (el, "Unexpected schema component that contains simpleTypeName that could not be resolved.");
500 private void InferAsEmptyElement (Element el, string ns,
503 ComplexType ct = el.SchemaType as ComplexType;
506 ct.ContentModel as SimpleModel;
508 ToEmptiableSimpleContent (sm, isNew);
512 ComplexModel cm = ct.ContentModel
515 ToEmptiableComplexContent (cm, isNew);
519 if (ct.Particle != null)
520 ct.Particle.MinOccurs = 0;
523 SimpleType st = el.SchemaType as SimpleType;
525 st = MakeBaseTypeAsEmptiable (st);
526 switch (st.QualifiedName.Namespace) {
527 case XmlSchema.Namespace:
529 el.SchemaTypeName = st.QualifiedName;
538 private SimpleType MakeBaseTypeAsEmptiable (SimpleType st)
540 switch (st.QualifiedName.Namespace) {
541 case XmlSchema.Namespace:
543 // If a primitive type
544 return XmlSchemaType.GetBuiltInSimpleType (
547 SimpleTypeRst str = st.Content as SimpleTypeRst;
550 foreach (SchemaFacet f in str.Facets) {
551 if (f is LengthFacet ||
552 f is MinLengthFacet) {
554 al = new ArrayList ();
558 foreach (SchemaFacet f in al)
559 str.Facets.Remove (f);
560 if (str.BaseType != null)
562 MakeBaseTypeAsEmptiable (st);
564 // It might have a reference to an
565 // external simple type, but there is
566 // no assurance that any of those
567 // external types allow an empty
568 // string. So just set base type as
570 str.BaseTypeName = QNameString;
571 } // union/list can have empty string value.
576 private void ToEmptiableSimpleContent (
577 SimpleModel sm, bool isNew)
579 SimpleExt se = sm.Content as SimpleExt;
581 se.BaseTypeName = QNameString;
583 SimpleRst sr = sm.Content
586 throw Error (sm, "Invalid simple content model was passed.");
587 sr.BaseTypeName = QNameString;
592 private void ToEmptiableComplexContent (
593 ComplexModel cm, bool isNew)
595 ComplexExt ce = cm.Content
598 if (ce.Particle != null)
599 ce.Particle.MinOccurs = 0;
600 else if (ce.BaseTypeName != null &&
601 ce.BaseTypeName != QName.Empty &&
602 ce.BaseTypeName != QNameAnyType)
603 throw Error (ce, "Complex type content extension has a reference to an external component that is not supported.");
606 ComplexRst cr = cm.Content
609 throw Error (cm, "Invalid complex content model was passed.");
610 if (cr.Particle != null)
611 cr.Particle.MinOccurs = 0;
612 else if (cr.BaseTypeName != null &&
613 cr.BaseTypeName != QName.Empty &&
614 cr.BaseTypeName != QNameAnyType)
615 throw Error (cr, "Complex type content extension has a reference to an external component that is not supported.");
619 private void InferContent (Element el, string ns, bool isNew)
622 source.MoveToContent ();
623 switch (source.NodeType) {
624 case XmlNodeType.EndElement:
625 InferAsEmptyElement (el, ns, isNew);
627 case XmlNodeType.Element:
628 InferComplexContent (el, ns, isNew);
630 case XmlNodeType.Text:
631 case XmlNodeType.CDATA:
632 case XmlNodeType.SignificantWhitespace:
633 InferTextContent (el, isNew);
634 source.MoveToContent ();
635 if (source.NodeType == XmlNodeType.Element)
636 goto case XmlNodeType.Element;
638 case XmlNodeType.Whitespace:
639 InferContent (el, ns, isNew); // skip and retry
644 private void InferComplexContent (Element el, string ns,
647 ComplexType ct = ToComplexType (el);
648 ToComplexContentType (ct);
651 bool consumed = false;
654 switch (source.NodeType) {
655 case XmlNodeType.Element:
656 Sequence s = PopulateSequence (ct);
657 Choice c = s.Items.Count > 0 ?
658 s.Items [0] as Choice :
663 ProcessSequence (ct, s, ns,
667 source.MoveToContent ();
669 case XmlNodeType.Text:
670 case XmlNodeType.CDATA:
671 case XmlNodeType.SignificantWhitespace:
673 source.ReadString ();
674 source.MoveToContent ();
676 case XmlNodeType.EndElement:
678 case XmlNodeType.None:
679 throw new NotImplementedException ("Internal Error: Should not happen.");
684 private void InferTextContent (Element el, bool isNew)
686 string value = source.ReadString ();
687 if (el.SchemaType == null) {
688 if (el.SchemaTypeName == QName.Empty) {
689 // no type information -> infer type
699 switch (el.SchemaTypeName.Namespace) {
700 case XmlSchema.Namespace:
702 // existing primitive type
703 el.SchemaTypeName = InferMergedType (
704 value, el.SchemaTypeName);
707 ComplexType ct = schemas.GlobalTypes [
710 // If it is complex, then just set
711 // mixed='true' (type cannot be set.)
712 // If it is simple, then we cannot
713 // make sure that string value is
714 // valid. So just set as xs:string.
718 el.SchemaTypeName = QNameString;
724 SimpleType st = el.SchemaType as SimpleType;
726 // If simple, then (described above)
727 el.SchemaType = null;
728 el.SchemaTypeName = QNameString;
733 ComplexType ect = el.SchemaType as ComplexType;
735 SimpleModel sm = ect.ContentModel as SimpleModel;
743 SimpleExt se = sm.Content as SimpleExt;
745 se.BaseTypeName = InferMergedType (value,
747 SimpleRst sr = sm.Content as SimpleRst;
749 sr.BaseTypeName = InferMergedType (value,
755 private void MarkAsMixed (ComplexType ct)
757 ComplexModel cm = ct.ContentModel as ComplexModel;
768 private void ProcessLax (Choice c, string ns)
770 foreach (Particle p in c.Items) {
771 Element el = p as Element;
773 throw Error (c, String.Format ("Target schema item contains unacceptable particle {0}. Only element is allowed here."));
774 if (ElementMatches (el, ns)) {
775 InferElement (el, ns, false);
779 // append a new element particle to lax term.
780 Element nel = new Element ();
781 if (source.NamespaceURI == ns)
782 nel.Name = source.LocalName;
784 nel.RefName = new QName (source.LocalName,
785 source.NamespaceURI);
786 InferElement (nel, source.NamespaceURI, true);
790 private bool ElementMatches (Element el, string ns)
792 bool matches = false;
793 if (el.RefName != QName.Empty) {
794 if (el.RefName.Name == source.LocalName &&
795 el.RefName.Namespace ==
799 else if (el.Name == source.LocalName &&
800 ns == source.NamespaceURI)
805 private void ProcessSequence (ComplexType ct, Sequence s,
806 string ns, ref int position, ref bool consumed,
809 for (int i = 0; i < position; i++) {
810 Element iel = s.Items [i] as Element;
811 if (ElementMatches (iel, ns)) {
812 // Sequence element type violation
813 // might happen (might not, but we
814 // cannot backtrack here). So switch
815 // to sequence of choice* here.
816 ProcessLax (ToSequenceOfChoice (s), ns);
821 if (s.Items.Count <= position) {
822 QName name = new QName (source.LocalName,
823 source.NamespaceURI);
824 Element nel = CreateElement (name);
825 InferElement (nel, ns, true);
826 if (ns == name.Namespace)
829 Element re = new Element ();
836 Element el = s.Items [position] as Element;
838 throw Error (s, String.Format ("Target complex type content sequence has an unacceptable type of particle {0}", s.Items [position]));
839 bool matches = ElementMatches (el, ns);
842 el.MaxOccursString = "unbounded";
843 InferElement (el, source.NamespaceURI, false);
844 source.MoveToContent ();
845 switch (source.NodeType) {
846 case XmlNodeType.None:
847 if (source.NodeType ==
849 goto case XmlNodeType.Element;
850 else if (source.NodeType ==
851 XmlNodeType.EndElement)
852 goto case XmlNodeType.EndElement;
854 case XmlNodeType.Element:
855 ProcessSequence (ct, s, ns, ref position,
856 ref consumed, isNew);
858 case XmlNodeType.Text:
859 case XmlNodeType.CDATA:
860 case XmlNodeType.SignificantWhitespace:
862 source.ReadString ();
863 goto case XmlNodeType.None;
864 case XmlNodeType.Whitespace:
865 source.ReadString ();
866 goto case XmlNodeType.None;
867 case XmlNodeType.EndElement:
878 ProcessSequence (ct, s, ns,
879 ref position, ref consumed,
883 ProcessLax (ToSequenceOfChoice (s), ns);
887 // Note that it does not return the changed sequence.
888 private Choice ToSequenceOfChoice (Sequence s)
890 Choice c = new Choice ();
893 c.MaxOccursString = "unbounded";
894 foreach (Particle p in s.Items)
901 // It makes complexType not to have Simple content model.
902 private void ToComplexContentType (ComplexType type)
904 SimpleModel sm = type.ContentModel as SimpleModel;
908 SOMList atts = GetAttributes (type);
909 foreach (SOMObject o in atts)
910 type.Attributes.Add (o);
911 // FIXME: need to copy AnyAttribute.
912 // (though not considered right now)
913 type.ContentModel = null;
917 private Sequence PopulateSequence (ComplexType ct)
919 Particle p = PopulateParticle (ct);
920 Sequence s = p as Sequence;
924 throw Error (ct, String.Format ("Target complexType contains unacceptable type of particle {0}", p));
927 private Sequence CreateSequence ()
929 Sequence s = new Sequence ();
935 private Particle PopulateParticle (ComplexType ct)
937 if (ct.ContentModel == null) {
938 if (ct.Particle == null)
939 ct.Particle = CreateSequence ();
942 ComplexModel cm = ct.ContentModel as ComplexModel;
944 ComplexExt ce = cm.Content as ComplexExt;
946 if (ce.Particle == null)
947 ce.Particle = CreateSequence ();
950 ComplexRst cr = cm.Content as ComplexRst;
952 if (cr.Particle == null)
953 cr.Particle = CreateSequence ();
957 throw Error (ct, "Schema inference internal error. The complexType should have been converted to have a complex content.");
964 // primitive type inference.
965 // When running lax type inference, it just returns xs:string.
966 private QName InferSimpleType (string value)
968 if (laxTypeInference)
972 // 0 and 1 are not infered as byte unlike MS.XSDInfer
980 long dec = XmlConvert.ToInt64 (value);
981 if (byte.MinValue <= dec && dec <= byte.MaxValue)
983 if (sbyte.MinValue <= dec && dec <= sbyte.MaxValue)
985 if (ushort.MinValue <= dec && dec <= ushort.MaxValue)
987 if (short.MinValue <= dec && dec <= short.MaxValue)
989 if (uint.MinValue <= dec && dec <= uint.MaxValue)
991 if (int.MinValue <= dec && dec <= int.MaxValue)
994 } catch (Exception) {
997 XmlConvert.ToUInt64 (value);
999 } catch (Exception) {
1002 XmlConvert.ToDecimal (value);
1003 return QNameDecimal;
1004 } catch (Exception) {
1007 double dbl = XmlConvert.ToDouble (value);
1008 if (float.MinValue <= dbl &&
1009 dbl <= float.MaxValue)
1013 } catch (Exception) {
1016 // FIXME: also try DateTimeSerializationMode
1018 XmlConvert.ToDateTime (value);
1019 return QNameDateTime;
1020 } catch (Exception) {
1023 XmlConvert.ToTimeSpan (value);
1024 return QNameDuration;
1025 } catch (Exception) {
1036 private Element GetGlobalElement (QName name)
1038 Element el = newElements [name] as Element;
1040 el = schemas.GlobalElements [name] as Element;
1044 private Attr GetGlobalAttribute (QName name)
1046 Attr a = newElements [name] as Attr;
1048 a = schemas.GlobalAttributes [name] as Attr;
1052 private Element CreateElement (QName name)
1054 Element el = new Element ();
1055 el.Name = name.Name;
1059 private Element CreateGlobalElement (QName name)
1061 Element el = CreateElement (name);
1062 XmlSchema schema = PopulateSchema (name.Namespace);
1063 schema.Items.Add (el);
1064 newElements.Add (name, el);
1068 private Attr CreateGlobalAttribute (QName name)
1070 Attr attr = new Attr ();
1071 XmlSchema schema = PopulateSchema (name.Namespace);
1072 attr.Name = name.Name;
1073 schema.Items.Add (attr);
1074 newAttributes.Add (name, attr);
1078 // Note that the return value never assures that all the
1079 // components in the parameter ns must reside in it.
1080 private XmlSchema PopulateSchema (string ns)
1082 ICollection list = schemas.Schemas (ns);
1083 if (list.Count > 0) {
1084 IEnumerator e = list.GetEnumerator ();
1086 return (XmlSchema) e.Current;
1088 XmlSchema s = new XmlSchema ();
1089 if (ns != null && ns.Length > 0)
1090 s.TargetNamespace = ns;
1091 s.ElementFormDefault = Form.Qualified;
1092 s.AttributeFormDefault = Form.Unqualified;
1097 private XmlSchemaInferenceException Error (
1098 XmlSchemaObject sourceObj,
1101 // This override is mainly for schema component error.
1102 return Error (sourceObj, false, message);
1105 private XmlSchemaInferenceException Error (
1106 XmlSchemaObject sourceObj,
1110 string msg = String.Concat (
1113 String.Format (". Related schema component is {0}",
1114 sourceObj.SourceUri,
1115 sourceObj.LineNumber,
1116 sourceObj.LinePosition) :
1119 String.Format (". {0}", source.BaseURI) :
1122 IXmlLineInfo li = source as IXmlLineInfo;
1123 if (useReader && li != null)
1124 return new XmlSchemaInferenceException (
1125 msg, null, li.LineNumber,
1128 return new XmlSchemaInferenceException (msg);