private QName InferMergedType(string value, QName typeName) { // examine value against specified type and // if unacceptable, then return a relaxed type. SimpleType st = XmlSchemaType.GetBuiltInSimpleType( typeName); if (st == null) // non-primitive type => see above. { return(QNameString); } do { try { st.Datatype.ParseValue(value, source.NameTable, source as IXmlNamespaceResolver); return(typeName); } catch { st = st.BaseXmlSchemaType as XmlSchemaSimpleType; typeName = st != null ? st.QualifiedName : QName.Empty; } } while (typeName != QName.Empty); return(QNameString); }
private Element CreateElement(QName name) { Element el = new Element(); el.Name = name.Name; return(el); }
private void Run() { // XmlSchemaSet need to be compiled. schemas.Compile(); // move to top-level element source.MoveToContent(); if (source.NodeType != XmlNodeType.Element) { throw new ArgumentException("Argument XmlReader content is expected to be an element."); } QName qname = new QName(source.LocalName, source.NamespaceURI); Element el = GetGlobalElement(qname); if (el == null) { el = CreateGlobalElement(qname); InferElement(el, qname.Namespace, true); } else { InferElement(el, qname.Namespace, false); } // FIXME: compile again. // foreach (XmlSchema schema in schemas.Schemas ()) // schemas.Reprocess (schema); }
private Element CreateGlobalElement(QName name) { Element el = CreateElement(name); XmlSchema schema = PopulateSchema(name.Namespace); schema.Items.Add(el); newElements.Add(name, el); return(el); }
private Attr CreateGlobalAttribute(QName name) { Attr attr = new Attr(); XmlSchema schema = PopulateSchema(name.Namespace); attr.Name = name.Name; schema.Items.Add(attr); newAttributes.Add(name, attr); return(attr); }
private Attr GetGlobalAttribute(QName name) { Attr a = newElements [name] as Attr; if (a == null) { a = schemas.GlobalAttributes [name] as Attr; } return(a); }
private Element GetGlobalElement(QName name) { Element el = newElements [name] as Element; if (el == null) { el = schemas.GlobalElements [name] as Element; } return(el); }
private XmlSchemaAttribute InferNewAttribute( QName attrName, bool isNewTypeDefinition, string ns) { Attr attr = null; bool mergedRequired = false; if (attrName.Namespace.Length > 0) { // global attribute; might be already defined. attr = GetGlobalAttribute(attrName) as Attr; if (attr == null) { attr = CreateGlobalAttribute(attrName); attr.SchemaTypeName = InferSimpleType(source.Value); } else { InferMergedAttribute(attr); mergedRequired = attr.Use == Use.Required; } attr = new Attr(); attr.RefName = attrName; AddImport(ns, attrName.Namespace); } else { // local attribute attr = new Attr(); attr.Name = attrName.Name; attr.SchemaTypeName = InferSimpleType(source.Value); } if (!laxOccurrence && (isNewTypeDefinition || mergedRequired)) { attr.Use = Use.Required; } else { attr.Use = Use.Optional; } return(attr); }
private ComplexType ToComplexType(Element el) { QName name = el.SchemaTypeName; XmlSchemaType type = el.SchemaType; // 1. element type is complex. ComplexType ct = type as ComplexType; if (ct != null) { return(ct); } // 2. reference to global complexType. XmlSchemaType globalType = schemas.GlobalTypes [name] as XmlSchemaType; ct = globalType as ComplexType; if (ct != null) { return(ct); } ct = new ComplexType(); el.SchemaType = ct; el.SchemaTypeName = QName.Empty; // 3. base type name is xs:anyType or no specification. // <xs:complexType /> if (name == QNameAnyType) { return(ct); } else if (type == null && name == QName.Empty) { return(ct); } SimpleModel sc = new SimpleModel(); ct.ContentModel = sc; // 4. type is simpleType // -> extension of existing simple type. SimpleType st = type as SimpleType; if (st != null) { SimpleRst scr = new SimpleRst(); scr.BaseType = st; sc.Content = scr; return(ct); } SimpleExt sce = new SimpleExt(); sc.Content = sce; // 5. type name points to primitive type // -> simple extension of a primitive type st = XmlSchemaType.GetBuiltInSimpleType(name); if (st != null) { sce.BaseTypeName = name; return(ct); } // 6. type name points to global simpleType. st = globalType as SimpleType; if (st != null) { sce.BaseTypeName = name; return(ct); } throw Error(el, "Unexpected schema component that contains simpleTypeName that could not be resolved."); }
private void InferAttributes(Element el, string ns, bool isNew) { // Now this element is going to have complexType. // It currently not, then we have to replace it. ComplexType ct = null; SOMList attList = null; Hashtable table = null; do { switch (source.NamespaceURI) { case NamespaceXml: if (schemas.Schemas( NamespaceXml).Count == 0) { IncludeXmlAttributes(); } break; case XmlSchema.InstanceNamespace: if (source.LocalName == "nil") { el.IsNillable = true; } // all other xsi:* atts are ignored continue; case NamespaceXmlns: continue; } if (ct == null) { ct = ToComplexType(el); attList = GetAttributes(ct); table = CollectAttrTable(attList); } QName attrName = new QName( source.LocalName, source.NamespaceURI); Attr attr = table [attrName] as Attr; if (attr == null) { attList.Add(InferNewAttribute( attrName, isNew, ns)); } else { table.Remove(attrName); if (attr.RefName != null && attr.RefName != QName.Empty) { continue; // just a reference } InferMergedAttribute(attr); } } while (source.MoveToNextAttribute()); // mark all attr definitions that did not appear // as optional. if (table != null) { foreach (Attr attr in table.Values) { attr.Use = Use.Optional; } } }
private void ProcessSequence(ComplexType ct, Sequence s, string ns, ref int position, ref bool consumed, bool isNew) { for (int i = 0; i < position; i++) { Element iel = s.Items [i] as Element; if (ElementMatches(iel, ns)) { // Sequence element type violation // might happen (might not, but we // cannot backtrack here). So switch // to sequence of choice* here. ProcessLax(ToSequenceOfChoice(s), ns); return; } } if (s.Items.Count <= position) { QName name = new QName(source.LocalName, source.NamespaceURI); Element nel = CreateElement(name); if (laxOccurrence) { nel.MinOccurs = 0; } InferElement(nel, ns, true); if (ns == name.Namespace) { s.Items.Add(nel); } else { Element re = new Element(); if (laxOccurrence) { re.MinOccurs = 0; } re.RefName = name; AddImport(ns, name.Namespace); s.Items.Add(re); } consumed = true; return; } Element el = s.Items [position] as Element; if (el == null) { throw Error(s, String.Format("Target complex type content sequence has an unacceptable type of particle {0}", s.Items [position])); } bool matches = ElementMatches(el, ns); if (matches) { if (consumed) { el.MaxOccursString = "unbounded"; } InferElement(el, source.NamespaceURI, false); source.MoveToContent(); switch (source.NodeType) { case XmlNodeType.None: if (source.NodeType == XmlNodeType.Element) { goto case XmlNodeType.Element; } else if (source.NodeType == XmlNodeType.EndElement) { goto case XmlNodeType.EndElement; } break; case XmlNodeType.Element: ProcessSequence(ct, s, ns, ref position, ref consumed, isNew); break; case XmlNodeType.Text: case XmlNodeType.CDATA: case XmlNodeType.SignificantWhitespace: MarkAsMixed(ct); source.ReadString(); goto case XmlNodeType.None; case XmlNodeType.Whitespace: source.ReadString(); goto case XmlNodeType.None; case XmlNodeType.EndElement: return; default: source.Read(); break; } } else { if (consumed) { position++; consumed = false; ProcessSequence(ct, s, ns, ref position, ref consumed, isNew); } else { ProcessLax(ToSequenceOfChoice(s), ns); } } }