Beispiel #1
0
        private void ProcessLax(Choice c, string ns)
        {
            foreach (Particle p in c.Items)
            {
                Element el = p as Element;
                if (el == null)
                {
                    throw Error(c, String.Format("Target schema item contains unacceptable particle {0}. Only element is allowed here."));
                }
                if (ElementMatches(el, ns))
                {
                    InferElement(el, ns, false);
                    return;
                }
            }
            // append a new element particle to lax term.
            Element nel = new Element();

            if (source.NamespaceURI == ns)
            {
                nel.Name = source.LocalName;
            }
            else
            {
                nel.RefName = new QName(source.LocalName,
                                        source.NamespaceURI);
                AddImport(ns, source.NamespaceURI);
            }
            InferElement(nel, source.NamespaceURI, true);
            c.Items.Add(nel);
        }
Beispiel #2
0
        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);
        }
Beispiel #3
0
        private void InferContent(Element el, string ns, bool isNew)
        {
            source.Read();
            source.MoveToContent();
            switch (source.NodeType)
            {
            case XmlNodeType.EndElement:
                InferAsEmptyElement(el, ns, isNew);
                break;

            case XmlNodeType.Element:
                InferComplexContent(el, ns, isNew);
                break;

            case XmlNodeType.Text:
            case XmlNodeType.CDATA:
            case XmlNodeType.SignificantWhitespace:
                InferTextContent(el, isNew);
                source.MoveToContent();
                if (source.NodeType == XmlNodeType.Element)
                {
                    goto case XmlNodeType.Element;
                }
                break;

            case XmlNodeType.Whitespace:
                InferContent(el, ns, isNew);                  // skip and retry
                break;
            }
        }
Beispiel #4
0
        private Element CreateElement(QName name)
        {
            Element el = new Element();

            el.Name = name.Name;
            return(el);
        }
Beispiel #5
0
        private Element CreateGlobalElement(QName name)
        {
            Element   el     = CreateElement(name);
            XmlSchema schema = PopulateSchema(name.Namespace);

            schema.Items.Add(el);
            newElements.Add(name, el);
            return(el);
        }
Beispiel #6
0
        private Element GetGlobalElement(QName name)
        {
            Element el = newElements [name] as Element;

            if (el == null)
            {
                el = schemas.GlobalElements [name] as Element;
            }
            return(el);
        }
Beispiel #7
0
        private void InferComplexContent(Element el, string ns,
                                         bool isNew)
        {
            ComplexType ct = ToComplexType(el);

            ToComplexContentType(ct);

            int  position = 0;
            bool consumed = false;

            do
            {
                switch (source.NodeType)
                {
                case XmlNodeType.Element:
                    Sequence s = PopulateSequence(ct);
                    Choice   c = s.Items.Count > 0 ?
                                 s.Items [0] as Choice :
                                 null;
                    if (c != null)
                    {
                        ProcessLax(c, ns);
                    }
                    else
                    {
                        ProcessSequence(ct, s, ns,
                                        ref position,
                                        ref consumed,
                                        isNew);
                    }
                    source.MoveToContent();
                    break;

                case XmlNodeType.Text:
                case XmlNodeType.CDATA:
                case XmlNodeType.SignificantWhitespace:
                    MarkAsMixed(ct);
                    source.ReadString();
                    source.MoveToContent();
                    break;

                case XmlNodeType.EndElement:
                    return;                     // finished

                case XmlNodeType.None:
                    throw new NotImplementedException("Internal Error: Should not happen.");
                }
            } while (true);
        }
Beispiel #8
0
        private void InferAsEmptyElement(Element el, string ns,
                                         bool isNew)
        {
            ComplexType ct = el.SchemaType as ComplexType;

            if (ct != null)
            {
                SimpleModel sm =
                    ct.ContentModel as SimpleModel;
                if (sm != null)
                {
                    ToEmptiableSimpleContent(sm, isNew);
                    return;
                }

                ComplexModel cm = ct.ContentModel
                                  as ComplexModel;
                if (cm != null)
                {
                    ToEmptiableComplexContent(cm, isNew);
                    return;
                }

                if (ct.Particle != null)
                {
                    ct.Particle.MinOccurs = 0;
                }
                return;
            }
            SimpleType st = el.SchemaType as SimpleType;

            if (st != null)
            {
                st = MakeBaseTypeAsEmptiable(st);
                switch (st.QualifiedName.Namespace)
                {
                case XmlSchema.Namespace:
                case XdtNamespace:
                    el.SchemaTypeName = st.QualifiedName;
                    break;

                default:
                    el.SchemaType = st;
                    break;
                }
            }
        }
Beispiel #9
0
        private void InferElement(Element el, string ns, bool isNew)
        {
            // Quick check for reference to another definition
            // (i.e. element ref='...' that should be redirected)
            if (el.RefName != QName.Empty)
            {
                Element body = GetGlobalElement(el.RefName);
                if (body == null)
                {
                    body = CreateElement(el.RefName);
                    InferElement(body, ns, true);
                }
                else
                {
                    InferElement(body, ns, isNew);
                }
                return;
            }

            // Attributes
            if (source.MoveToFirstAttribute())
            {
                InferAttributes(el, ns, isNew);
                source.MoveToElement();
            }

            // Content
            if (source.IsEmptyElement)
            {
                InferAsEmptyElement(el, ns, isNew);
                source.Read();
                source.MoveToContent();
            }
            else
            {
                InferContent(el, ns, isNew);
                source.ReadEndElement();
            }
            if (el.SchemaType == null &&
                el.SchemaTypeName == QName.Empty)
            {
                el.SchemaTypeName = QNameString;
            }
        }
Beispiel #10
0
        private bool ElementMatches(Element el, string ns)
        {
            bool matches = false;

            if (el.RefName != QName.Empty)
            {
                if (el.RefName.Name == source.LocalName &&
                    el.RefName.Namespace ==
                    source.NamespaceURI)
                {
                    matches = true;
                }
            }
            else if (el.Name == source.LocalName &&
                     ns == source.NamespaceURI)
            {
                matches = true;
            }
            return(matches);
        }
Beispiel #11
0
        private void InferTextContent(Element el, bool isNew)
        {
            string value = source.ReadString();

            if (el.SchemaType == null)
            {
                if (el.SchemaTypeName == QName.Empty)
                {
                    // no type information -> infer type
                    if (isNew)
                    {
                        el.SchemaTypeName =
                            InferSimpleType(
                                value);
                    }
                    else
                    {
                        el.SchemaTypeName =
                            QNameString;
                    }
                    return;
                }
                switch (el.SchemaTypeName.Namespace)
                {
                case XmlSchema.Namespace:
                case XdtNamespace:
                    // existing primitive type
                    el.SchemaTypeName = InferMergedType(
                        value, el.SchemaTypeName);
                    break;

                default:
                    ComplexType ct = schemas.GlobalTypes [
                        el.SchemaTypeName]
                                     as ComplexType;
                    // If it is complex, then just set
                    // mixed='true' (type cannot be set.)
                    // If it is simple, then we cannot
                    // make sure that string value is
                    // valid. So just set as xs:string.
                    if (ct != null)
                    {
                        MarkAsMixed(ct);
                    }
                    else
                    {
                        el.SchemaTypeName = QNameString;
                    }
                    break;
                }
                return;
            }
            // simpleType
            SimpleType st = el.SchemaType as SimpleType;

            if (st != null)
            {
                // If simple, then (described above)
                el.SchemaType     = null;
                el.SchemaTypeName = QNameString;
                return;
            }

            // complexType
            ComplexType ect = el.SchemaType as ComplexType;

            SimpleModel sm = ect.ContentModel as SimpleModel;

            if (sm == null)
            {
                // - ComplexContent
                MarkAsMixed(ect);
                return;
            }

            // - SimpleContent
            SimpleExt se = sm.Content as SimpleExt;

            if (se != null)
            {
                se.BaseTypeName = InferMergedType(value,
                                                  se.BaseTypeName);
            }
            SimpleRst sr = sm.Content as SimpleRst;

            if (sr != null)
            {
                sr.BaseTypeName = InferMergedType(value,
                                                  sr.BaseTypeName);
                sr.BaseType = null;
            }
        }
Beispiel #12
0
        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.");
        }
Beispiel #13
0
        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;
                }
            }
        }
Beispiel #14
0
        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);
                }
            }
        }