private TypeModel CreateTypeModel(Uri source, XmlSchemaAttributeGroup attributeGroup, NamespaceModel namespaceModel, XmlQualifiedName qualifiedName, List <DocumentationModel> docs)
        {
            var name = "I" + ToTitleCase(qualifiedName.Name);

            if (namespaceModel != null)
            {
                name = namespaceModel.GetUniqueTypeName(name);
            }

            var interfaceModel = new InterfaceModel(_configuration)
            {
                Name          = name,
                Namespace     = namespaceModel,
                XmlSchemaName = qualifiedName
            };

            interfaceModel.Documentation.AddRange(docs);

            if (namespaceModel != null)
            {
                namespaceModel.Types[name] = interfaceModel;
            }
            if (!qualifiedName.IsEmpty)
            {
                Types[qualifiedName] = interfaceModel;
            }

            var items      = attributeGroup.Attributes;
            var properties = CreatePropertiesForAttributes(source, interfaceModel, items.OfType <XmlSchemaAttribute>());

            interfaceModel.Properties.AddRange(properties);
            var interfaces = items.OfType <XmlSchemaAttributeGroupRef>()
                             .Select(a => (InterfaceModel)CreateTypeModel(CodeUtilities.CreateUri(a.SourceUri), AttributeGroups[a.RefName], a.RefName));

            interfaceModel.Interfaces.AddRange(interfaces);

            return(interfaceModel);
        }
        private TypeModel CreateTypeModel(Uri source, XmlSchemaComplexType complexType, NamespaceModel namespaceModel, XmlQualifiedName qualifiedName, List <DocumentationModel> docs)
        {
            var name = _configuration.NamingProvider.ComplexTypeNameFromQualifiedName(qualifiedName);

            if (namespaceModel != null)
            {
                name = namespaceModel.GetUniqueTypeName(name);
            }

            var classModel = new ClassModel(_configuration)
            {
                Name           = name,
                Namespace      = namespaceModel,
                XmlSchemaName  = qualifiedName,
                XmlSchemaType  = complexType,
                IsAbstract     = complexType.IsAbstract,
                IsAnonymous    = string.IsNullOrEmpty(complexType.QualifiedName.Name),
                IsMixed        = complexType.IsMixed,
                IsSubstitution = complexType.Parent is XmlSchemaElement && !((XmlSchemaElement)complexType.Parent).SubstitutionGroup.IsEmpty
            };

            classModel.Documentation.AddRange(docs);

            if (namespaceModel != null)
            {
                namespaceModel.Types[classModel.Name] = classModel;
            }

            if (!qualifiedName.IsEmpty)
            {
                var key = BuildKey(complexType, qualifiedName);
                Types[key] = classModel;
            }

            if (complexType.BaseXmlSchemaType != null && complexType.BaseXmlSchemaType.QualifiedName != AnyType)
            {
                var baseModel = CreateTypeModel(source, complexType.BaseXmlSchemaType, complexType.BaseXmlSchemaType.QualifiedName);
                classModel.BaseClass = baseModel;
                if (baseModel is ClassModel baseClassModel)
                {
                    baseClassModel.DerivedTypes.Add(classModel);
                }
            }

            XmlSchemaParticle particle = null;

            if (classModel.BaseClass != null)
            {
                if (complexType.ContentModel.Content is XmlSchemaComplexContentExtension complexContent)
                {
                    particle = complexContent.Particle;
                }

                // If it's a restriction, do not duplicate elements on the derived class, they're already in the base class.
                // See https://msdn.microsoft.com/en-us/library/f3z3wh0y.aspx
            }
            else
            {
                particle = complexType.Particle ?? complexType.ContentTypeParticle;
            }

            var items = GetElements(particle, complexType).ToList();

            if (_configuration.GenerateInterfaces)
            {
                var interfaces = items.Select(i => i.XmlParticle).OfType <XmlSchemaGroupRef>()
                                 .Select(i => (InterfaceModel)CreateTypeModel(CodeUtilities.CreateUri(i.SourceUri), Groups[i.RefName], i.RefName)).ToList();

                classModel.AddInterfaces(interfaces);
            }

            var properties = CreatePropertiesForElements(source, classModel, particle, items);

            classModel.Properties.AddRange(properties);

            XmlSchemaObjectCollection attributes = null;

            if (classModel.BaseClass != null)
            {
                if (complexType.ContentModel.Content is XmlSchemaComplexContentExtension complexContent)
                {
                    attributes = complexContent.Attributes;
                }
                else if (complexType.ContentModel.Content is XmlSchemaSimpleContentExtension simpleContent)
                {
                    attributes = simpleContent.Attributes;
                }

                // If it's a restriction, do not duplicate attributes on the derived class, they're already in the base class.
                // See https://msdn.microsoft.com/en-us/library/f3z3wh0y.aspx
            }
            else
            {
                attributes = complexType.Attributes;
            }

            if (attributes != null)
            {
                var attributeProperties = CreatePropertiesForAttributes(source, classModel, attributes.Cast <XmlSchemaObject>());
                classModel.Properties.AddRange(attributeProperties);

                if (_configuration.GenerateInterfaces)
                {
                    var attributeInterfaces = attributes.OfType <XmlSchemaAttributeGroupRef>()
                                              .Select(i => (InterfaceModel)CreateTypeModel(CodeUtilities.CreateUri(i.SourceUri), AttributeGroups[i.RefName], i.RefName));
                    classModel.AddInterfaces(attributeInterfaces);
                }
            }

            if (complexType.AnyAttribute != null)
            {
                var property = new PropertyModel(_configuration)
                {
                    OwningType = classModel,
                    Name       = "AnyAttribute",
                    Type       = new SimpleModel(_configuration)
                    {
                        ValueType = typeof(XmlAttribute), UseDataTypeAttribute = false
                    },
                    IsAttribute  = true,
                    IsCollection = true,
                    IsAny        = true
                };

                var attributeDocs = GetDocumentation(complexType.AnyAttribute);
                property.Documentation.AddRange(attributeDocs);

                classModel.Properties.Add(property);
            }

            return(classModel);
        }
        private void CreateElements(IEnumerable <XmlSchemaElement> elements)
        {
            foreach (var rootElement in elements)
            {
                var rootSchema    = rootElement.GetSchema();
                var source        = CodeUtilities.CreateUri(rootSchema.SourceUri);
                var qualifiedName = rootElement.ElementSchemaType.QualifiedName;
                if (qualifiedName.IsEmpty)
                {
                    qualifiedName = rootElement.QualifiedName;
                }
                var type = CreateTypeModel(source, rootElement.ElementSchemaType, qualifiedName);

                if (type.RootElementName != null)
                {
                    if (type is ClassModel classModel)
                    {
                        // There is already another global element with this type.
                        // Need to create an empty derived class.

                        var derivedClassModel = new ClassModel(_configuration)
                        {
                            Name      = _configuration.NamingProvider.RootClassNameFromQualifiedName(rootElement.QualifiedName),
                            Namespace = CreateNamespaceModel(source, rootElement.QualifiedName)
                        };

                        derivedClassModel.Documentation.AddRange(GetDocumentation(rootElement));

                        if (derivedClassModel.Namespace != null)
                        {
                            derivedClassModel.Name = derivedClassModel.Namespace.GetUniqueTypeName(derivedClassModel.Name);
                            derivedClassModel.Namespace.Types[derivedClassModel.Name] = derivedClassModel;
                        }

                        var key = BuildKey(rootElement, rootElement.QualifiedName);
                        Types[key] = derivedClassModel;

                        derivedClassModel.BaseClass = classModel;
                        ((ClassModel)derivedClassModel.BaseClass).DerivedTypes.Add(derivedClassModel);

                        derivedClassModel.RootElementName = rootElement.QualifiedName;
                    }
                    else
                    {
                        var key = BuildKey(rootElement, rootElement.QualifiedName);
                        Types[key] = type;
                    }
                }
                else
                {
                    if (type is ClassModel classModel)
                    {
                        classModel.Documentation.AddRange(GetDocumentation(rootElement));
                        if (!rootElement.SubstitutionGroup.IsEmpty)
                        {
                            classModel.IsSubstitution   = true;
                            classModel.SubstitutionName = rootElement.QualifiedName;
                        }
                    }

                    type.RootElementName = rootElement.QualifiedName;
                }
            }
        }
示例#4
0
 public override CodeAttributeDeclaration GetAttribute()
 {
     return(new CodeAttributeDeclaration(CodeUtilities.CreateTypeReference(typeof(RegularExpressionAttribute), Configuration),
                                         new CodeAttributeArgument(new CodePrimitiveExpression(Value))));
 }
        public ModelBuilder(GeneratorConfiguration configuration, XmlSchemaSet set)
        {
            _configuration = configuration;
            _set           = set;

            DocumentationModel.DisableComments = _configuration.DisableComments;
            var objectModel = new SimpleModel(_configuration)
            {
                Name                 = "AnyType",
                Namespace            = CreateNamespaceModel(new Uri(XmlSchema.Namespace), AnyType),
                XmlSchemaName        = AnyType,
                XmlSchemaType        = null,
                ValueType            = typeof(object),
                UseDataTypeAttribute = false
            };

            Types[AnyType] = objectModel;

            AttributeGroups = set.Schemas().Cast <XmlSchema>().SelectMany(s => s.AttributeGroups.Values.Cast <XmlSchemaAttributeGroup>())
                              .DistinctBy(g => g.QualifiedName.ToString())
                              .ToDictionary(g => g.QualifiedName);
            Groups = set.Schemas().Cast <XmlSchema>().SelectMany(s => s.Groups.Values.Cast <XmlSchemaGroup>())
                     .DistinctBy(g => g.QualifiedName.ToString())
                     .ToDictionary(g => g.QualifiedName);

            foreach (var globalType in set.GlobalTypes.Values.Cast <XmlSchemaType>())
            {
                var schema = globalType.GetSchema();
                var source = CodeUtilities.CreateUri(schema?.SourceUri);
                CreateTypeModel(source, globalType, globalType.QualifiedName);
            }

            foreach (var rootElement in set.GlobalElements.Values.Cast <XmlSchemaElement>())
            {
                var rootSchema    = rootElement.GetSchema();
                var source        = CodeUtilities.CreateUri(rootSchema.SourceUri);
                var qualifiedName = rootElement.ElementSchemaType.QualifiedName;
                if (qualifiedName.IsEmpty)
                {
                    qualifiedName = rootElement.QualifiedName;
                }
                var type = CreateTypeModel(source, rootElement.ElementSchemaType, qualifiedName);

                if (type.RootElementName != null)
                {
                    if (type is ClassModel classModel)
                    {
                        // There is already another global element with this type.
                        // Need to create an empty derived class.

                        var derivedClassModel = new ClassModel(_configuration)
                        {
                            Name      = ToTitleCase(rootElement.QualifiedName.Name),
                            Namespace = CreateNamespaceModel(source, rootElement.QualifiedName)
                        };

                        derivedClassModel.Documentation.AddRange(GetDocumentation(rootElement));

                        if (derivedClassModel.Namespace != null)
                        {
                            derivedClassModel.Name = derivedClassModel.Namespace.GetUniqueTypeName(derivedClassModel.Name);
                            derivedClassModel.Namespace.Types[derivedClassModel.Name] = derivedClassModel;
                        }

                        Types[rootElement.QualifiedName] = derivedClassModel;

                        derivedClassModel.BaseClass = classModel;
                        ((ClassModel)derivedClassModel.BaseClass).DerivedTypes.Add(derivedClassModel);

                        derivedClassModel.RootElementName = rootElement.QualifiedName;
                    }
                    else
                    {
                        Types[rootElement.QualifiedName] = type;
                    }
                }
                else
                {
                    if (type is ClassModel classModel)
                    {
                        classModel.Documentation.AddRange(GetDocumentation(rootElement));
                        if (!rootElement.SubstitutionGroup.IsEmpty)
                        {
                            classModel.IsSubstitution   = true;
                            classModel.SubstitutionName = rootElement.QualifiedName;
                        }
                    }

                    type.RootElementName = rootElement.QualifiedName;
                }
            }
        }