private QilNode CompileAttribute(NodeCtor node)
{
QilNode qilNs = CompileStringAvt(node.NsAvt);
QilNode qilName = CompileStringAvt(node.NameAvt);
QilNode qname;
bool explicitNamespace = false;
if (qilName.NodeType == QilNodeType.LiteralString && (qilNs == null || qilNs.NodeType == QilNodeType.LiteralString))
{
string name = (string)(QilLiteral)qilName;
string prefix, local, nsUri;
bool isValid = _compiler.ParseQName(name, out prefix, out local, (IErrorHelper)this);
if (qilNs == null)
{
nsUri = isValid ? ResolvePrefix(/*ignoreDefaultNs:*/true, prefix) : _compiler.CreatePhantomNamespace();
}
else
{
nsUri = (string)(QilLiteral)qilNs;
// if both name and ns are non AVT and this ns is already bind to the same prefix we can avoid reseting ns management
explicitNamespace = true;
}
// Check the case <xsl:attribute name="foo:xmlns" namespace=""/>
if (name == "xmlns" || local == "xmlns" && nsUri.Length == 0)
{
ReportError(/*[XT_031]*/SR.Xslt_XmlnsAttr, "name", name);
}
qname = _f.QName(local, nsUri, prefix);
}
else
{
// Process AVT
if (qilNs != null)
{
qname = _f.StrParseQName(qilName, qilNs);
}
else
{
qname = ResolveQNameDynamic(/*ignoreDefaultNs:*/true, qilName);
}
}
if (explicitNamespace)
{
// Optimization: attribute cannot change the default namespace
_outputScope.InvalidateNonDefaultPrefixes();
}
return _f.AttributeCtor(qname, CompileInstructions(node.Content));
}