private static void FacetsEquivalentTo(XmlSchemaObjectCollection expected, XmlSchemaObjectCollection actual) { List <XmlSchemaFacet> actualFacets = actual .Cast <XmlSchemaFacet>() .ToList(); foreach (XmlSchemaFacet expectedFacet in expected.Cast <XmlSchemaFacet>()) { bool found = false; for (int i = 0; i < actualFacets.Count; i++) { if (FacetEquals(expectedFacet, actualFacets[i])) { found = true; actualFacets.RemoveAt(i); break; } } if (!found) { throw new ContainsException(expectedFacet, actual); } } if (actualFacets.Count > 0) { throw new DoesNotContainException(expected, actualFacets.First()); } }
/// <summary> /// Returns the attributes within a collection. Most of the time, this will /// simply normalize the name and convert the structure into the resultant /// output type. /// </summary> /// <param name="xsModel">The xs model.</param> /// <param name="attributes">The attributes.</param> /// <returns></returns> internal IEnumerable <SchemaItemAttribute> GetAttributes( XmlSchema xsModel, XmlSchemaObjectCollection attributes) { foreach (var attr in attributes.Cast <XmlSchemaAttribute>()) { var name = attr.QualifiedName; if (name.IsEmpty) { if (attr.Form == XmlSchemaForm.Qualified) { name = new XmlQualifiedName(attr.Name, xsModel.TargetNamespace); } else { name = new XmlQualifiedName(attr.Name, null); } } var schemaType = ResolveSchemaType(xsModel, attr.SchemaTypeName); var itemAttribute = new SchemaItemAttribute( name.Namespace, name.Name, schemaType as XmlSchemaSimpleType, attr.SchemaTypeName.Name); yield return(itemAttribute); } }
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); }
// ReSharper disable once FunctionComplexityOverflow private TypeModel CreateTypeModel(Uri source, XmlSchemaAnnotated type, XmlQualifiedName qualifiedName) { TypeModel typeModel; if (!qualifiedName.IsEmpty && Types.TryGetValue(qualifiedName, out typeModel)) { return(typeModel); } if (source == null) { throw new ArgumentNullException("source"); } var namespaceModel = CreateNamespaceModel(source, qualifiedName); var docs = GetDocumentation(type); var group = type as XmlSchemaGroup; if (group != null) { 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 particle = group.Particle; var items = GetElements(particle); var properties = CreatePropertiesForElements(source, interfaceModel, particle, items.Where(i => !(i.XmlParticle is XmlSchemaGroupRef))); interfaceModel.Properties.AddRange(properties); var interfaces = items.Select(i => i.XmlParticle).OfType <XmlSchemaGroupRef>() .Select(i => (InterfaceModel)CreateTypeModel(new Uri(i.SourceUri), Groups[i.RefName], i.RefName)); interfaceModel.Interfaces.AddRange(interfaces); return(interfaceModel); } var attributeGroup = type as XmlSchemaAttributeGroup; if (attributeGroup != null) { 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(new Uri(a.SourceUri), AttributeGroups[a.RefName], a.RefName)); interfaceModel.Interfaces.AddRange(interfaces); return(interfaceModel); } var complexType = type as XmlSchemaComplexType; if (complexType != null) { var name = ToTitleCase(qualifiedName.Name); if (namespaceModel != null) { name = namespaceModel.GetUniqueTypeName(name); } var classModel = new ClassModel(_configuration) { Name = name, Namespace = namespaceModel, XmlSchemaName = qualifiedName, XmlSchemaType = complexType, IsAbstract = complexType.IsAbstract, IsAnonymous = complexType.QualifiedName.Name == "", IsMixed = complexType.IsMixed, IsSubstitution = complexType.Parent is XmlSchemaElement && !((XmlSchemaElement)complexType.Parent).SubstitutionGroup.IsEmpty, EnableDataBinding = EnableDataBinding, }; classModel.Documentation.AddRange(docs); if (namespaceModel != null) { namespaceModel.Types[classModel.Name] = classModel; } if (!qualifiedName.IsEmpty) { Types[qualifiedName] = 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) { ((ClassModel)classModel.BaseClass).DerivedTypes.Add(classModel); } } XmlSchemaParticle particle = null; if (classModel.BaseClass != null) { if (complexType.ContentModel.Content is XmlSchemaComplexContentExtension) { particle = ((XmlSchemaComplexContentExtension)complexType.ContentModel.Content).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 if (complexType.ContentModel.Content is XmlSchemaComplexContentRestriction) // particle = ((XmlSchemaComplexContentRestriction)complexType.ContentModel.Content).Particle; } else { particle = complexType.ContentTypeParticle; } var items = GetElements(particle); var properties = CreatePropertiesForElements(source, classModel, particle, items); classModel.Properties.AddRange(properties); if (GenerateInterfaces) { var interfaces = items.Select(i => i.XmlParticle).OfType <XmlSchemaGroupRef>() .Select(i => (InterfaceModel)CreateTypeModel(new Uri(i.SourceUri), Groups[i.RefName], i.RefName)); classModel.Interfaces.AddRange(interfaces); } XmlSchemaObjectCollection attributes = null; if (classModel.BaseClass != null) { if (complexType.ContentModel.Content is XmlSchemaComplexContentExtension) { attributes = ((XmlSchemaComplexContentExtension)complexType.ContentModel.Content).Attributes; } else if (complexType.ContentModel.Content is XmlSchemaSimpleContentExtension) { attributes = ((XmlSchemaSimpleContentExtension)complexType.ContentModel.Content).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 if (complexType.ContentModel.Content is XmlSchemaComplexContentRestriction) // attributes = ((XmlSchemaComplexContentRestriction)complexType.ContentModel.Content).Attributes; //else if (complexType.ContentModel.Content is XmlSchemaSimpleContentRestriction) // attributes = ((XmlSchemaSimpleContentRestriction)complexType.ContentModel.Content).Attributes; } else { attributes = complexType.Attributes; } if (attributes != null) { var attributeProperties = CreatePropertiesForAttributes(source, classModel, attributes.Cast <XmlSchemaObject>()); classModel.Properties.AddRange(attributeProperties); if (GenerateInterfaces) { var attributeInterfaces = attributes.OfType <XmlSchemaAttributeGroupRef>() .Select(i => (InterfaceModel)CreateTypeModel(new Uri(i.SourceUri), AttributeGroups[i.RefName], i.RefName)); classModel.Interfaces.AddRange(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); } var simpleType = type as XmlSchemaSimpleType; if (simpleType != null) { var restrictions = new List <RestrictionModel>(); var typeRestriction = simpleType.Content as XmlSchemaSimpleTypeRestriction; if (typeRestriction != null) { var enumFacets = typeRestriction.Facets.OfType <XmlSchemaEnumerationFacet>().ToList(); var isEnum = (enumFacets.Count == typeRestriction.Facets.Count && enumFacets.Count != 0) || (EnumTypes.Contains(typeRestriction.BaseTypeName.Name) && enumFacets.Any()); if (isEnum) { // we got an enum var name = ToTitleCase(qualifiedName.Name); if (namespaceModel != null) { name = namespaceModel.GetUniqueTypeName(name); } var enumModel = new EnumModel(_configuration) { Name = name, Namespace = namespaceModel, XmlSchemaName = qualifiedName, XmlSchemaType = simpleType, }; enumModel.Documentation.AddRange(docs); foreach (var facet in enumFacets.DistinctBy(f => f.Value)) { var value = new EnumValueModel { Name = ToTitleCase(facet.Value).ToNormalizedEnumName(), Value = facet.Value }; var valueDocs = GetDocumentation(facet); value.Documentation.AddRange(valueDocs); var deprecated = facet.Annotation != null && facet.Annotation.Items.OfType <XmlSchemaAppInfo>() .Any(a => a.Markup.Any(m => m.Name == "annox:annotate" && m.HasChildNodes && m.FirstChild.Name == "jl:Deprecated")); value.IsDeprecated = deprecated; enumModel.Values.Add(value); } if (namespaceModel != null) { namespaceModel.Types[enumModel.Name] = enumModel; } if (!qualifiedName.IsEmpty) { Types[qualifiedName] = enumModel; } return(enumModel); } restrictions = GetRestrictions(typeRestriction.Facets.Cast <XmlSchemaFacet>(), simpleType).Where(r => r != null).Sanitize().ToList(); } var simpleModelName = ToTitleCase(qualifiedName.Name); if (namespaceModel != null) { simpleModelName = namespaceModel.GetUniqueTypeName(simpleModelName); } var simpleModel = new SimpleModel(_configuration) { Name = simpleModelName, Namespace = namespaceModel, XmlSchemaName = qualifiedName, XmlSchemaType = simpleType, ValueType = simpleType.Datatype.GetEffectiveType(_configuration), }; simpleModel.Documentation.AddRange(docs); simpleModel.Restrictions.AddRange(restrictions); if (namespaceModel != null) { namespaceModel.Types[simpleModel.Name] = simpleModel; } if (!qualifiedName.IsEmpty) { Types[qualifiedName] = simpleModel; } return(simpleModel); } throw new Exception(string.Format("Cannot build declaration for {0}", qualifiedName)); }