in src/org/apache/xerces/dom/DOMNormalizer.java [752:1043]
protected final void namespaceFixUp (ElementImpl element, AttributeMap attributes){
if (DEBUG) {
System.out.println("[ns-fixup] element:" +element.getNodeName()+
" uri: "+element.getNamespaceURI());
}
// ------------------------------------
// pick up local namespace declarations
// <xsl:stylesheet xmlns:xsl="http://xslt">
// <!-- add the following via DOM
// body is bound to http://xslt
// -->
// <xsl:body xmlns:xsl="http://bound"/>
//
// ------------------------------------
String value, uri, prefix;
if (attributes != null) {
// Record all valid local declarations
for (int k = 0; k < attributes.getLength(); ++k) {
Attr attr = (Attr)attributes.getItem(k);
uri = attr.getNamespaceURI();
if (uri != null && uri.equals(NamespaceContext.XMLNS_URI)) {
// namespace attribute
value = attr.getNodeValue();
if (value == null) {
value=XMLSymbols.EMPTY_STRING;
}
// Check for invalid namespace declaration:
if (fDocument.errorChecking && value.equals(NamespaceContext.XMLNS_URI)) {
//A null value for locale is passed to formatMessage,
//which means that the default locale will be used
fLocator.fRelatedNode = attr;
String msg = DOMMessageFormatter.formatMessage(DOMMessageFormatter.XML_DOMAIN,"CantBindXMLNS",null );
reportDOMError(fErrorHandler, fError, fLocator, msg, DOMError.SEVERITY_ERROR, "CantBindXMLNS");
} else {
// XML 1.0 Attribute value normalization
// value = normalizeAttributeValue(value, attr);
prefix = attr.getPrefix();
prefix = (prefix == null ||
prefix.length() == 0) ? XMLSymbols.EMPTY_STRING :fSymbolTable.addSymbol(prefix);
String localpart = fSymbolTable.addSymbol( attr.getLocalName());
if (prefix == XMLSymbols.PREFIX_XMLNS) { //xmlns:prefix
value = fSymbolTable.addSymbol(value);
if (value.length() != 0) {
fNamespaceContext.declarePrefix(localpart, value);
} else {
// REVISIT: issue error on invalid declarations
// xmlns:foo = ""
}
//removeDefault (attr, attributes);
continue;
} else { // (localpart == fXmlnsSymbol && prefix == fEmptySymbol) -- xmlns
// empty prefix is always bound ("" or some string)
value = fSymbolTable.addSymbol(value);
fNamespaceContext.declarePrefix(XMLSymbols.EMPTY_STRING, value.length() != 0 ? value : null);
//removeDefault (attr, attributes);
continue;
}
} // end-else: valid declaration
} // end-if: namespace attribute
}
}
// ---------------------------------------------------------
// Fix up namespaces for element: per DOM L3
// Need to consider the following cases:
//
// case 1: <xsl:stylesheet xmlns:xsl="http://xsl">
// We create another element body bound to the "http://xsl" namespace
// as well as namespace attribute rebounding xsl to another namespace.
// <xsl:body xmlns:xsl="http://another">
// Need to make sure that the new namespace decl value is changed to
// "http://xsl"
//
// ---------------------------------------------------------
// check if prefix/namespace is correct for current element
// ---------------------------------------------------------
uri = element.getNamespaceURI();
prefix = element.getPrefix();
if (uri != null) { // Element has a namespace
uri = fSymbolTable.addSymbol(uri);
prefix = (prefix == null ||
prefix.length() == 0) ? XMLSymbols.EMPTY_STRING :fSymbolTable.addSymbol(prefix);
if (fNamespaceContext.getURI(prefix) == uri) {
// The xmlns:prefix=namespace or xmlns="default" was declared at parent.
// The binder always stores mapping of empty prefix to "".
} else {
// the prefix is either undeclared
// or
// conflict: the prefix is bound to another URI
addNamespaceDecl(prefix, uri, element);
fLocalNSBinder.declarePrefix(prefix, uri);
fNamespaceContext.declarePrefix(prefix, uri);
}
} else { // Element has no namespace
if (element.getLocalName() == null) {
// Error: DOM Level 1 node!
if (fNamespaceValidation) {
String msg = DOMMessageFormatter.formatMessage(
DOMMessageFormatter.DOM_DOMAIN, "NullLocalElementName",
new Object[]{element.getNodeName()});
reportDOMError(fErrorHandler, fError, fLocator, msg, DOMError.SEVERITY_FATAL_ERROR,
"NullLocalElementName");
} else {
String msg = DOMMessageFormatter.formatMessage(
DOMMessageFormatter.DOM_DOMAIN, "NullLocalElementName",
new Object[]{element.getNodeName()});
reportDOMError(fErrorHandler, fError, fLocator, msg, DOMError.SEVERITY_ERROR,
"NullLocalElementName");
}
} else { // uri=null and no colon (DOM L2 node)
uri = fNamespaceContext.getURI(XMLSymbols.EMPTY_STRING);
if (uri !=null && uri.length() > 0) {
// undeclare default namespace declaration (before that element
// bound to non-zero length uir), but adding xmlns="" decl
addNamespaceDecl (XMLSymbols.EMPTY_STRING, XMLSymbols.EMPTY_STRING, element);
fLocalNSBinder.declarePrefix(XMLSymbols.EMPTY_STRING, null);
fNamespaceContext.declarePrefix(XMLSymbols.EMPTY_STRING, null);
}
}
}
// -----------------------------------------
// Fix up namespaces for attributes: per DOM L3
// check if prefix/namespace is correct the attributes
// -----------------------------------------
if (attributes != null) {
// clone content of the attributes
attributes.cloneMap(fAttributeList);
for (int i = 0; i < fAttributeList.size(); i++) {
Attr attr = (Attr) fAttributeList.get(i);
fLocator.fRelatedNode = attr;
if (DEBUG) {
System.out.println("==>[ns-fixup] process attribute: "+attr.getNodeName());
}
// normalize attribute value
attr.normalize();
value = attr.getValue();
uri = attr.getNamespaceURI();
// make sure that value is never null.
if (value == null) {
value = XMLSymbols.EMPTY_STRING;
}
//---------------------------------------
// check if value of the attribute is namespace well-formed
//---------------------------------------
if (fDocument.errorChecking && ((fConfiguration.features & DOMConfigurationImpl.WELLFORMED) != 0)) {
isAttrValueWF(fErrorHandler, fError, fLocator, attributes, attr, value, fDocument.isXML11Version());
if (fDocument.isXMLVersionChanged()) {
boolean wellformed;
if (fNamespaceValidation){
wellformed = CoreDocumentImpl.isValidQName(attr.getPrefix(), attr.getLocalName(), fDocument.isXML11Version());
}
else {
wellformed = CoreDocumentImpl.isXMLName(attr.getNodeName(), fDocument.isXML11Version());
}
if (!wellformed) {
String msg = DOMMessageFormatter.formatMessage(
DOMMessageFormatter.DOM_DOMAIN,
"wf-invalid-character-in-node-name",
new Object[]{"Attr", attr.getNodeName()});
reportDOMError(fErrorHandler, fError, fLocator, msg, DOMError.SEVERITY_ERROR,
"wf-invalid-character-in-node-name");
}
}
}
if (uri != null) { // attribute has namespace !=null
prefix = attr.getPrefix();
prefix = (prefix == null ||
prefix.length() == 0) ? XMLSymbols.EMPTY_STRING :fSymbolTable.addSymbol(prefix);
/*String localpart =*/ fSymbolTable.addSymbol( attr.getLocalName());
// ---------------------------------------
// skip namespace declarations
// ---------------------------------------
// REVISIT: can we assume that "uri" is from some symbol
// table, and compare by reference? -SG
if (uri != null && uri.equals(NamespaceContext.XMLNS_URI)) {
continue;
}
// ---------------------------------------
// remove default attributes
// ---------------------------------------
/*
if (removeDefault(attr, attributes)) {
continue;
}
*/
// XML 1.0 Attribute value normalization
//value = normalizeAttributeValue(value, attr);
// reset id-attributes
((AttrImpl)attr).setIdAttribute(false);
uri = fSymbolTable.addSymbol(uri);
// find if for this prefix a URI was already declared
String declaredURI = fNamespaceContext.getURI(prefix);
if (prefix == XMLSymbols.EMPTY_STRING || declaredURI != uri) {
// attribute has no prefix (default namespace decl does not apply to attributes)
// OR
// attribute prefix is not declared
// OR
// conflict: attribute has a prefix that conficlicts with a binding
// already active in scope
// Find if any prefix for attributes namespace URI is available
// in the scope
String declaredPrefix = fNamespaceContext.getPrefix(uri);
if (declaredPrefix !=null && declaredPrefix !=XMLSymbols.EMPTY_STRING) {
// use the prefix that was found (declared previously for this URI
prefix = declaredPrefix;
} else {
if (prefix != XMLSymbols.EMPTY_STRING && fLocalNSBinder.getURI(prefix) == null) {
// the current prefix is not null and it has no in scope declaration
// use this prefix
} else {
// find a prefix following the pattern "NS" +index (starting at 1)
// make sure this prefix is not declared in the current scope.
int counter = 1;
prefix = fSymbolTable.addSymbol(PREFIX +counter++);
while (fLocalNSBinder.getURI(prefix)!=null) {
prefix = fSymbolTable.addSymbol(PREFIX +counter++);
}
}
// add declaration for the new prefix
addNamespaceDecl(prefix, uri, element);
value = fSymbolTable.addSymbol(value);
fLocalNSBinder.declarePrefix(prefix, value);
fNamespaceContext.declarePrefix(prefix, uri);
}
// change prefix for this attribute
attr.setPrefix(prefix);
}
} else { // attribute uri == null
// XML 1.0 Attribute value normalization
//value = normalizeAttributeValue(value, attr);
// reset id-attributes
((AttrImpl)attr).setIdAttribute(false);
if (attr.getLocalName() == null) {
// It is an error if document has DOM L1 nodes.
if (fNamespaceValidation) {
String msg = DOMMessageFormatter.formatMessage(
DOMMessageFormatter.DOM_DOMAIN,
"NullLocalAttrName", new Object[]{attr.getNodeName()});
reportDOMError(fErrorHandler, fError, fLocator, msg, DOMError.SEVERITY_FATAL_ERROR,
"NullLocalAttrName");
} else {
String msg = DOMMessageFormatter.formatMessage(
DOMMessageFormatter.DOM_DOMAIN,
"NullLocalAttrName", new Object[]{attr.getNodeName()});
reportDOMError(fErrorHandler, fError, fLocator, msg, DOMError.SEVERITY_ERROR,
"NullLocalAttrName");
}
} else {
// uri=null and no colon
// no fix up is needed: default namespace decl does not
// ---------------------------------------
// remove default attributes
// ---------------------------------------
// removeDefault(attr, attributes);
}
}
}
} // end loop for attributes
}