/// <summary> /// Determine whether an ElementCtor, AttributeCtor, or NamespaceDecl's namespace is already declared. If it is, /// set the IsNamespaceInScope property to True. Otherwise, add the namespace to the set of in-scope namespaces if /// addInScopeNmsp is True. Return false if the name is computed or is invalid. /// </summary> private bool CheckNamespaceInScope(QilBinary nd) { QilName ndName; string prefix, ns, prefixExisting, nsExisting; XPathNodeType nodeType; switch (nd.NodeType) { case QilNodeType.ElementCtor: case QilNodeType.AttributeCtor: ndName = nd.Left as QilName; if (ndName != null) { prefix = ndName.Prefix; ns = ndName.NamespaceUri; nodeType = (nd.NodeType == QilNodeType.ElementCtor) ? XPathNodeType.Element : XPathNodeType.Attribute; break; } // Not a literal name, so return false return(false); default: Debug.Assert(nd.NodeType == QilNodeType.NamespaceDecl); prefix = (string)(QilLiteral)nd.Left; ns = (string)(QilLiteral)nd.Right; nodeType = XPathNodeType.Namespace; break; } // Attribute with null namespace and xmlns:xml are always in-scope if (nd.NodeType == QilNodeType.AttributeCtor && ns.Length == 0 || prefix == "xml" && ns == XmlReservedNs.NsXml) { XmlILConstructInfo.Write(nd).IsNamespaceInScope = true; return(true); } // Don't process names that are invalid if (!ValidateNames.ValidateName(prefix, string.Empty, ns, nodeType, ValidateNames.Flags.CheckPrefixMapping)) { return(false); } // Atomize names prefix = _nsmgr.NameTable.Add(prefix); ns = _nsmgr.NameTable.Add(ns); // Determine whether namespace is already in-scope for (int iNmsp = 0; iNmsp < _cntNmsp; iNmsp++) { _nsmgr.GetNamespaceDeclaration(iNmsp, out prefixExisting, out nsExisting); // If prefix is already declared, if ((object)prefix == (object)prefixExisting) { // Then if the namespace is the same, this namespace is redundant if ((object)ns == (object)nsExisting) { XmlILConstructInfo.Write(nd).IsNamespaceInScope = true; } // Else quit searching, because any further matching prefixes will be hidden (not in-scope) Debug.Assert(nd.NodeType != QilNodeType.NamespaceDecl || !_nsmgr.HasNamespace(prefix) || _nsmgr.LookupNamespace(prefix) == ns, "Compilers must ensure that namespace declarations do not conflict with the namespace used by the element constructor."); break; } } // If not in-scope, then add if it's allowed if (_addInScopeNmsp) { _nsmgr.AddNamespace(prefix, ns); _cntNmsp++; } return(true); }