private XmlSchemaAttribute AddAttribute()

in src/dotnet-svcutil/lib/src/FrameworkFork/Microsoft.Xml/Xml/schema/Inference/infer.cs [288:498]


        private XmlSchemaAttribute AddAttribute(string localName, string prefix, string childURI, string attrValue, bool bCreatingNewType, XmlSchema parentSchema, XmlSchemaObjectCollection addLocation, XmlSchemaObjectTable compiledAttributes)
        {
            if (childURI == XmlSchema.Namespace)
            {
                throw new XmlSchemaInferenceException(ResXml.SchInf_schema, 0, 0);
            }

            XmlSchemaAttribute xsa = null;
            int AttributeType = -1;
            XmlSchemaAttribute returnedAttribute = null;    //this value will change to attributeReference if childURI!= parentURI
            XmlSchema xs = null;
            bool add = true;

            Debug.Assert(compiledAttributes != null); //AttributeUses is never null
                                                      // First we need to look into the already compiled attributes 
                                                      //   (they come from the schemaset which we got on input)
                                                      // If there are none or we don't find it there, then we must search the list of attributes
                                                      //   where we are going to add a new one (if it doesn't exist). 
                                                      //   This is necessary to avoid adding duplicate attribute declarations.
            ICollection searchCollectionPrimary, searchCollectionSecondary;
            if (compiledAttributes.Count > 0)
            {
                searchCollectionPrimary = compiledAttributes.Values;
                searchCollectionSecondary = addLocation;
            }
            else
            {
                searchCollectionPrimary = addLocation;
                searchCollectionSecondary = null;
            }
            if (childURI == XmlReservedNs.NsXml)
            {
                XmlSchemaAttribute attributeReference = null;
                //see if the reference exists
                attributeReference = FindAttributeRef(searchCollectionPrimary, localName, childURI);
                if (attributeReference == null && searchCollectionSecondary != null)
                {
                    attributeReference = FindAttributeRef(searchCollectionSecondary, localName, childURI);
                }
                if (attributeReference == null)
                {
                    attributeReference = new XmlSchemaAttribute();
                    attributeReference.RefName = new XmlQualifiedName(localName, childURI);
                    if (bCreatingNewType && this.Occurrence == InferenceOption.Restricted)
                    {
                        attributeReference.Use = XmlSchemaUse.Required;
                    }
                    else
                    {
                        attributeReference.Use = XmlSchemaUse.Optional;
                    }

                    addLocation.Add(attributeReference);
                }
                returnedAttribute = attributeReference;
            }
            else
            {
                if (childURI.Length == 0)
                {
                    xs = parentSchema;
                    add = false;
                }
                else if (childURI != null && !_schemaSet.Contains(childURI))
                {
                    /*if (parentSchema.AttributeFormDefault = XmlSchemaForm.Unqualified && childURI.Length == 0)
                {
                    xs = parentSchema;
                    add = false;
                    break;
                }*/
                    xs = new XmlSchema();
                    xs.AttributeFormDefault = XmlSchemaForm.Unqualified;
                    xs.ElementFormDefault = XmlSchemaForm.Qualified;
                    if (childURI.Length != 0)
                        xs.TargetNamespace = childURI;
                    //schemas.Add(childURI, xs);
                    _schemaSet.Add(xs);
                    if (prefix.Length != 0 && String.Compare(prefix, "xml", StringComparison.OrdinalIgnoreCase) != 0)
                        _namespaceManager.AddNamespace(prefix, childURI);
                }
                else
                {
                    ArrayList col = _schemaSet.Schemas(childURI) as ArrayList;
                    if (col != null && col.Count > 0)
                    {
                        xs = col[0] as XmlSchema;
                    }
                }
                if (childURI.Length != 0) //BUGBUG It need not be an attribute reference if there is a namespace, it can be attribute with attributeFormDefault = qualified
                {
                    XmlSchemaAttribute attributeReference = null;
                    //see if the reference exists
                    attributeReference = FindAttributeRef(searchCollectionPrimary, localName, childURI);
                    if (attributeReference == null & searchCollectionSecondary != null)
                    {
                        attributeReference = FindAttributeRef(searchCollectionSecondary, localName, childURI);
                    }
                    if (attributeReference == null)
                    {
                        attributeReference = new XmlSchemaAttribute();
                        attributeReference.RefName = new XmlQualifiedName(localName, childURI);
                        if (bCreatingNewType && this.Occurrence == InferenceOption.Restricted)
                        {
                            attributeReference.Use = XmlSchemaUse.Required;
                        }
                        else
                        {
                            attributeReference.Use = XmlSchemaUse.Optional;
                        }

                        addLocation.Add(attributeReference);
                    }
                    returnedAttribute = attributeReference;

                    //see if the attribute exists on the global level
                    xsa = FindAttribute(xs.Items, localName);
                    if (xsa == null)
                    {
                        xsa = new XmlSchemaAttribute();
                        xsa.Name = localName;
                        xsa.SchemaTypeName = RefineSimpleType(attrValue, ref AttributeType);
                        xsa.LineNumber = AttributeType; //we use LineNumber to store flags of valid types
                        xs.Items.Add(xsa);
                    }
                    else
                    {
                        if (xsa.Parent == null)
                        {
                            AttributeType = xsa.LineNumber; // we use LineNumber to store flags of valid types
                        }
                        else
                        {
                            AttributeType = GetSchemaType(xsa.SchemaTypeName);
                            xsa.Parent = null;
                        }
                        xsa.SchemaTypeName = RefineSimpleType(attrValue, ref AttributeType);
                        xsa.LineNumber = AttributeType; // we use LineNumber to store flags of valid types
                    }
                }
                else
                {
                    xsa = FindAttribute(searchCollectionPrimary, localName);
                    if (xsa == null && searchCollectionSecondary != null)
                    {
                        xsa = FindAttribute(searchCollectionSecondary, localName);
                    }
                    if (xsa == null)
                    {
                        xsa = new XmlSchemaAttribute();
                        xsa.Name = localName;
                        xsa.SchemaTypeName = RefineSimpleType(attrValue, ref AttributeType);
                        xsa.LineNumber = AttributeType; // we use LineNumber to store flags of valid types
                        if (bCreatingNewType && this.Occurrence == InferenceOption.Restricted)
                            xsa.Use = XmlSchemaUse.Required;
                        else
                            xsa.Use = XmlSchemaUse.Optional;
                        addLocation.Add(xsa);
                        if (xs.AttributeFormDefault != XmlSchemaForm.Unqualified)
                        {
                            xsa.Form = XmlSchemaForm.Unqualified;
                        }
                    }
                    else
                    {
                        if (xsa.Parent == null)
                        {
                            AttributeType = xsa.LineNumber; // we use LineNumber to store flags of valid types
                        }
                        else
                        {
                            AttributeType = GetSchemaType(xsa.SchemaTypeName);
                            xsa.Parent = null;
                        }
                        xsa.SchemaTypeName = RefineSimpleType(attrValue, ref AttributeType);
                        xsa.LineNumber = AttributeType; // we use LineNumber to store flags of valid types
                    }
                    returnedAttribute = xsa;
                }
            }
            string nullString = null;
            if (add && childURI != parentSchema.TargetNamespace)
            {
                for (int i = 0; i < parentSchema.Includes.Count; ++i)
                {
                    XmlSchemaImport import = parentSchema.Includes[i] as XmlSchemaImport;
                    if (import == null)
                    {
                        continue;
                    }
                    if (import.Namespace == childURI)
                    {
                        add = false;
                    }
                }
                if (add)
                {
                    XmlSchemaImport import = new XmlSchemaImport();
                    import.Schema = xs;
                    if (childURI.Length != 0)
                    {
                        nullString = childURI;
                    }
                    import.Namespace = nullString;
                    parentSchema.Includes.Add(import);
                }
            }


            return returnedAttribute;
        }