private void ParseAttlistDecl()
{
if (GetToken(true) != Token.QName)
{
goto UnexpectedError;
}
// element name
XmlQualifiedName elementName = GetNameQualified(true);
SchemaElementDecl elementDecl;
if (!_schemaInfo.ElementDecls.TryGetValue(elementName, out elementDecl))
{
if (!_schemaInfo.UndeclaredElementDecls.TryGetValue(elementName, out elementDecl))
{
elementDecl = new SchemaElementDecl(elementName, elementName.Namespace);
_schemaInfo.UndeclaredElementDecls.Add(elementName, elementDecl);
}
}
SchemaAttDef attrDef = null;
for (;;)
{
switch (GetToken(false))
{
case Token.QName:
XmlQualifiedName attrName = GetNameQualified(true);
attrDef = new SchemaAttDef(attrName, attrName.Namespace);
attrDef.IsDeclaredInExternal = !ParsingInternalSubset;
attrDef.LineNumber = (int)LineNo;
attrDef.LinePosition = (int)LinePos - (_curPos - _tokenStartPos);
break;
case Token.GreaterThan:
#if !SILVERLIGHT
if (_v1Compat)
{
// check xml:space and xml:lang
// BUG BUG: For backward compatibility, we check the correct type and values of the
// xml:space attribute only on the last attribute in the list.
// See Webdata bugs #97457 and #93935.
if (attrDef != null && attrDef.Prefix.Length > 0 && attrDef.Prefix.Equals("xml") && attrDef.Name.Name == "space")
{
attrDef.Reserved = SchemaAttDef.Reserve.XmlSpace;
if (attrDef.Datatype.TokenizedType != XmlTokenizedType.ENUMERATION)
{
Throw(SR.Xml_EnumerationRequired, string.Empty, attrDef.LineNumber, attrDef.LinePosition);
}
if (_validate)
{
attrDef.CheckXmlSpace(_readerAdapterWithValidation.ValidationEventHandling);
}
}
}
#endif
return;
default:
goto UnexpectedError;
}
bool attrDefAlreadyExists = (elementDecl.GetAttDef(attrDef.Name) != null);
ParseAttlistType(attrDef, elementDecl, attrDefAlreadyExists);
ParseAttlistDefault(attrDef, attrDefAlreadyExists);
// check xml:space and xml:lang
if (attrDef.Prefix.Length > 0 && attrDef.Prefix.Equals("xml"))
{
if (attrDef.Name.Name == "space")
{
#if !SILVERLIGHT
if (_v1Compat)
{
// BUG BUG: For backward compatibility, we check the correct type and values of the
// xml:space attribute only on the last attribute in the list, and mark it as reserved
// only its value is correct (=prevent XmlTextReader from fhrowing on invalid value).
// See Webdata bugs #98168, #97457 and #93935.
string val = attrDef.DefaultValueExpanded.Trim();
if (val.Equals("preserve") || val.Equals("default"))
{
attrDef.Reserved = SchemaAttDef.Reserve.XmlSpace;
}
}
else
{
#endif
attrDef.Reserved = SchemaAttDef.Reserve.XmlSpace;
if (attrDef.TokenizedType != XmlTokenizedType.ENUMERATION)
{
Throw(SR.Xml_EnumerationRequired, string.Empty, attrDef.LineNumber, attrDef.LinePosition);
}
#if !SILVERLIGHT
if (_validate)
{
attrDef.CheckXmlSpace(_readerAdapterWithValidation.ValidationEventHandling);
}
}
#endif
}
else if (attrDef.Name.Name == "lang")
{
attrDef.Reserved = SchemaAttDef.Reserve.XmlLang;
}
}
// add attribute to element decl
if (!attrDefAlreadyExists)
{
elementDecl.AddAttDef(attrDef);
}
}
UnexpectedError:
OnUnexpectedError();
}