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;
}