예제 #1
0
        private void Read(XmlSchemaObject obj)
        {
            var xmlSchema = (XmlSchema)obj;

            Id = xmlSchema.Id;
            TargetNamespace    = xmlSchema.TargetNamespace;
            Version            = xmlSchema.Version;
            ElementFormDefault = xmlSchema.ElementFormDefault;

            foreach (var ns in xmlSchema.Namespaces.ToArray())
            {
                Namespaces.Add(ns);
            }

            foreach (var import in xmlSchema.Includes.OfType <XmlSchemaImport>())
            {
                Imports.Add(import);
            }

            var elements = xmlSchema.Items.OfType <XmlSchemaElement>().ToDictionary(element => element.SchemaTypeName);
            var types    = new Dictionary <XmlQualifiedName, SDataSchemaType>();
            var lists    = new Dictionary <XmlQualifiedName, XmlSchemaComplexType>();

            foreach (var item in xmlSchema.Items.OfType <XmlSchemaType>())
            {
                SDataSchemaType type;
                var             qualifiedName = new XmlQualifiedName(item.Name, TargetNamespace);

                if (item is XmlSchemaComplexType)
                {
                    var xmlComplexType = (XmlSchemaComplexType)item;

                    if (xmlComplexType.Particle == null || xmlComplexType.Particle is XmlSchemaAll)
                    {
                        XmlSchemaElement element;

                        if (elements.TryGetValue(qualifiedName, out element))
                        {
                            var roleAttr = element.UnhandledAttributes != null
                                               ? element.UnhandledAttributes.FirstOrDefault(attr => attr.NamespaceURI == SmeNamespaceUri && attr.LocalName == "role")
                                               : null;

                            if (roleAttr == null)
                            {
                                throw new InvalidOperationException(string.Format("Role attribute on top level element '{0}' not found", element.Name));
                            }

                            switch (roleAttr.Value)
                            {
                            case "resourceKind":
                                type = new SDataSchemaResourceType();
                                break;

                            case "serviceOperation":
                                type = new SDataSchemaServiceOperationType();
                                break;

                            case "query":
                                type = new SDataSchemaNamedQueryType();
                                break;

                            default:
                                throw new InvalidOperationException(string.Format("Unexpected role attribute value '{0}' on top level element '{1}'", roleAttr.Value, element.Name));
                            }

                            type.Read(element);
                            elements.Remove(qualifiedName);
                        }
                        else
                        {
                            type = new SDataSchemaComplexType();
                        }
                    }
                    else if (xmlComplexType.Particle is XmlSchemaSequence)
                    {
                        var sequence = (XmlSchemaSequence)xmlComplexType.Particle;

                        if (sequence.Items.Count != 1)
                        {
                            throw new InvalidOperationException(string.Format("Particle on list complex type '{0}' does not contain exactly one element", xmlComplexType.Name));
                        }

                        var element = sequence.Items[0] as XmlSchemaElement;

                        if (element == null)
                        {
                            throw new InvalidOperationException(string.Format("Unexpected sequence item type '{0}' on list complex type '{1}'", sequence.Items[0].GetType(), xmlComplexType.Name));
                        }

                        SDataSchemaType complexType;

                        if (types.TryGetValue(element.SchemaTypeName, out complexType))
                        {
                            complexType.ListName         = xmlComplexType.Name;
                            complexType.ListItemName     = element.Name;
                            complexType.ListAnyAttribute = xmlComplexType.AnyAttribute;
                            types.Remove(element.SchemaTypeName);
                        }
                        else
                        {
                            lists.Add(element.SchemaTypeName, xmlComplexType);
                        }

                        continue;
                    }
                    else if (xmlComplexType.Particle is XmlSchemaChoice)
                    {
                        type = new SDataSchemaChoiceType();
                    }
                    else
                    {
                        throw new InvalidOperationException(string.Format("Unexpected particle type '{0}' on complex type '{1}'", xmlComplexType.Particle.GetType(), xmlComplexType.Name));
                    }
                }
                else if (item is XmlSchemaSimpleType)
                {
                    var simpleType = (XmlSchemaSimpleType)item;

                    if (simpleType.Content == null)
                    {
                        throw new InvalidOperationException(string.Format("Missing content on simple type '{0}'", simpleType.Name));
                    }

                    var restriction = simpleType.Content as XmlSchemaSimpleTypeRestriction;

                    if (restriction == null)
                    {
                        throw new InvalidOperationException(string.Format("Unexpected content type '{0}' on simple type '{1}'", simpleType.Content.GetType(), simpleType.Name));
                    }

                    if (restriction.Facets.Cast <XmlSchemaObject>().All(facet => facet is XmlSchemaEnumerationFacet))
                    {
                        type = new SDataSchemaEnumType();
                    }
                    else
                    {
                        type = new SDataSchemaSimpleType();
                    }
                }
                else
                {
                    throw new InvalidOperationException(string.Format("Unexpected item type '{0}'", item.GetType()));
                }

                XmlSchemaComplexType complexList;
                if (lists.TryGetValue(qualifiedName, out complexList))
                {
                    var sequence    = (XmlSchemaSequence)complexList.Particle;
                    var itemElement = (XmlSchemaElement)sequence.Items[0];

                    type.ListName         = complexList.Name;
                    type.ListItemName     = itemElement.Name;
                    type.ListAnyAttribute = complexList.AnyAttribute;
                    lists.Remove(qualifiedName);
                }
                else
                {
                    types.Add(qualifiedName, type);
                }

                type.Read(item);
                Types.Add(type);
            }

            Compile();
        }
        private void Read(XmlSchemaObject obj)
        {
            var xmlSchema = (XmlSchema) obj;
            Id = xmlSchema.Id;
            TargetNamespace = xmlSchema.TargetNamespace;
            Version = xmlSchema.Version;
            ElementFormDefault = xmlSchema.ElementFormDefault;

            foreach (var ns in xmlSchema.Namespaces.ToArray())
            {
                Namespaces.Add(ns);
            }

            foreach (var import in xmlSchema.Includes.OfType<XmlSchemaImport>())
            {
                Imports.Add(import);
            }

            var elements = xmlSchema.Items.OfType<XmlSchemaElement>().ToDictionary(element => element.SchemaTypeName);
            var types = new Dictionary<XmlQualifiedName, SDataSchemaType>();
            var lists = new Dictionary<XmlQualifiedName, XmlSchemaComplexType>();

            foreach (var item in xmlSchema.Items.OfType<XmlSchemaType>())
            {
                SDataSchemaType type;
                var qualifiedName = new XmlQualifiedName(item.Name, TargetNamespace);

                if (item is XmlSchemaComplexType)
                {
                    var xmlComplexType = (XmlSchemaComplexType) item;

                    if (xmlComplexType.Particle == null || xmlComplexType.Particle is XmlSchemaAll)
                    {
                        XmlSchemaElement element;

                        if (elements.TryGetValue(qualifiedName, out element))
                        {
                            var roleAttr = element.UnhandledAttributes != null
                                               ? element.UnhandledAttributes.FirstOrDefault(attr => attr.NamespaceURI == SmeNamespaceUri && attr.LocalName == "role")
                                               : null;

                            if (roleAttr == null)
                            {
                                throw new InvalidOperationException(string.Format("Role attribute on top level element '{0}' not found", element.Name));
                            }

                            switch (roleAttr.Value)
                            {
                                case "resourceKind":
                                    type = new SDataSchemaResourceType();
                                    break;
                                case "serviceOperation":
                                    type = new SDataSchemaServiceOperationType();
                                    break;
                                case "query":
                                    type = new SDataSchemaNamedQueryType();
                                    break;
                                default:
                                    throw new InvalidOperationException(string.Format("Unexpected role attribute value '{0}' on top level element '{1}'", roleAttr.Value, element.Name));
                            }

                            type.Read(element);
                            elements.Remove(qualifiedName);
                        }
                        else
                        {
                            type = new SDataSchemaComplexType();
                        }
                    }
                    else if (xmlComplexType.Particle is XmlSchemaSequence)
                    {
                        var sequence = (XmlSchemaSequence) xmlComplexType.Particle;

                        if (sequence.Items.Count != 1)
                        {
                            throw new InvalidOperationException(string.Format("Particle on list complex type '{0}' does not contain exactly one element", xmlComplexType.Name));
                        }

                        var element = sequence.Items[0] as XmlSchemaElement;

                        if (element == null)
                        {
                            throw new InvalidOperationException(string.Format("Unexpected sequence item type '{0}' on list complex type '{1}'", sequence.Items[0].GetType(), xmlComplexType.Name));
                        }

                        SDataSchemaType complexType;

                        if (types.TryGetValue(element.SchemaTypeName, out complexType))
                        {
                            complexType.ListName = xmlComplexType.Name;
                            complexType.ListItemName = element.Name;
                            complexType.ListAnyAttribute = xmlComplexType.AnyAttribute;
                            types.Remove(element.SchemaTypeName);
                        }
                        else
                        {
                            lists.Add(element.SchemaTypeName, xmlComplexType);
                        }

                        continue;
                    }
                    else if (xmlComplexType.Particle is XmlSchemaChoice)
                    {
                        type = new SDataSchemaChoiceType();
                    }
                    else
                    {
                        throw new InvalidOperationException(string.Format("Unexpected particle type '{0}' on complex type '{1}'", xmlComplexType.Particle.GetType(), xmlComplexType.Name));
                    }
                }
                else if (item is XmlSchemaSimpleType)
                {
                    var simpleType = (XmlSchemaSimpleType) item;

                    if (simpleType.Content == null)
                    {
                        throw new InvalidOperationException(string.Format("Missing content on simple type '{0}'", simpleType.Name));
                    }

                    var restriction = simpleType.Content as XmlSchemaSimpleTypeRestriction;

                    if (restriction == null)
                    {
                        throw new InvalidOperationException(string.Format("Unexpected content type '{0}' on simple type '{1}'", simpleType.Content.GetType(), simpleType.Name));
                    }

                    if (restriction.Facets.Cast<XmlSchemaObject>().All(facet => facet is XmlSchemaEnumerationFacet))
                    {
                        type = new SDataSchemaEnumType();
                    }
                    else
                    {
                        type = new SDataSchemaSimpleType();
                    }
                }
                else
                {
                    throw new InvalidOperationException(string.Format("Unexpected item type '{0}'", item.GetType()));
                }

                XmlSchemaComplexType complexList;
                if (lists.TryGetValue(qualifiedName, out complexList))
                {
                    var sequence = (XmlSchemaSequence) complexList.Particle;
                    var itemElement = (XmlSchemaElement) sequence.Items[0];

                    type.ListName = complexList.Name;
                    type.ListItemName = itemElement.Name;
                    type.ListAnyAttribute = complexList.AnyAttribute;
                    lists.Remove(qualifiedName);
                }
                else
                {
                    types.Add(qualifiedName, type);
                }

                type.Read(item);
                Types.Add(type);
            }

            Compile();
        }