public override void WriteStartAttribute(string prefix, string localName, string ns) {
try {
AutoComplete(Token.StartAttribute);
this.specialAttr = SpecialAttr.None;
if (this.namespaces) {
if (prefix != null && prefix.Length == 0) {
prefix = null;
}
if (ns == XmlReservedNs.NsXmlNs && prefix == null && localName != "xmlns") {
prefix = "xmlns";
}
if (prefix == "xml") {
if (localName == "lang") {
this.specialAttr = SpecialAttr.XmlLang;
}
else if (localName == "space") {
this.specialAttr = SpecialAttr.XmlSpace;
}
/* bug54408. to be fwd compatible we need to treat xml prefix as reserved
and not really insist on a specific value. Who knows in the future it
might be OK to say xml:blabla
else {
throw new ArgumentException(Res.GetString(Res.Xml_InvalidPrefix));
}*/
}
else if (prefix == "xmlns") {
if (XmlReservedNs.NsXmlNs != ns && ns != null) {
throw new ArgumentException(Res.GetString(Res.Xml_XmlnsBelongsToReservedNs));
}
if (localName == null || localName.Length == 0) {
localName = prefix;
prefix = null;
this.prefixForXmlNs = null;
}
else {
this.prefixForXmlNs = localName;
}
this.specialAttr = SpecialAttr.XmlNs;
}
else if (prefix == null && localName == "xmlns") {
if (XmlReservedNs.NsXmlNs != ns && ns != null) {
// add the below line back in when DOM is fixed
throw new ArgumentException(Res.GetString(Res.Xml_XmlnsBelongsToReservedNs));
}
this.specialAttr = SpecialAttr.XmlNs;
this.prefixForXmlNs = null;
}
else {
if (ns == null) {
// use defined prefix
if (prefix != null && (LookupNamespace(prefix) == -1)) {
throw new ArgumentException(Res.GetString(Res.Xml_UndefPrefix));
}
}
else if (ns.Length == 0) {
// empty namespace require null prefix
prefix = string.Empty;
}
else { // ns.Length != 0
VerifyPrefixXml(prefix, ns);
if (prefix != null && LookupNamespaceInCurrentScope(prefix) != -1) {
prefix = null;
}
// Now verify prefix validity
string definedPrefix = FindPrefix(ns);
if (definedPrefix != null && (prefix == null || prefix == definedPrefix)) {
prefix = definedPrefix;
}
else {
if (prefix == null) {
prefix = GeneratePrefix(); // need a prefix if
}
PushNamespace(prefix, ns, false);
}
}
}
if (prefix != null && prefix.Length != 0) {
textWriter.Write(prefix);
textWriter.Write(':');
}
}
else {
if ((ns != null && ns.Length != 0) || (prefix != null && prefix.Length != 0)) {
throw new ArgumentException(Res.GetString(Res.Xml_NoNamespaces));
}
if (localName == "xml:lang") {
this.specialAttr = SpecialAttr.XmlLang;
}
else if (localName == "xml:space") {
this.specialAttr = SpecialAttr.XmlSpace;
}
}
xmlEncoder.StartAttribute(this.specialAttr != SpecialAttr.None);
textWriter.Write(localName);
textWriter.Write('=');
if (this.curQuoteChar != this.quoteChar) {
this.curQuoteChar = this.quoteChar;
xmlEncoder.QuoteChar = this.quoteChar;
}
textWriter.Write(this.curQuoteChar);
}
catch {
currentState = State.Error;
throw;
}
}