FileDocCategorySizeDatePackage
DOMNormalizer.javaAPI DocJava SE 5 API89471Fri Aug 26 14:55:42 BST 2005com.sun.org.apache.xerces.internal.dom

DOMNormalizer

public class DOMNormalizer extends Object implements XMLDocumentHandler
This class adds implementation for normalizeDocument method. It acts as if the document was going through a save and load cycle, putting the document in a "normal" form. The actual result depends on the features being set and governing what operations actually take place. See setNormalizationFeature for details. Noticeably this method normalizes Text nodes, makes the document "namespace wellformed", according to the algorithm described below in pseudo code, by adding missing namespace declaration attributes and adding or changing namespace prefixes, updates the replacement tree of EntityReference nodes, normalizes attribute values, etc. Mutation events, when supported, are generated to reflect the changes occuring on the document. See Namespace normalization for details on how namespace declaration attributes and prefixes are normalized. NOTE: There is an initial support for DOM revalidation with XML Schema as a grammar. The tree might not be validated correctly if entityReferences, CDATA sections are present in the tree. The PSVI information is not exposed, normalized data (including element default content is not available). NOTE: the implementation is experimental and methods, functionality can be modified or removed in the future.
author
Elena Litani, IBM
author
Neeraj Bajaj, Sun Microsystems, inc.
version
$Id: DOMNormalizer.java,v 1.54 2004/04/22 20:39:03 mrglavas Exp $

Fields Summary
public static final String
SYMBOL_TABLE
Property identifier: symbol table.
public static final String
GRAMMAR_POOL
Property identifier: grammar pool.
protected static final String
NAMESPACES_FEATURE_ID
Namespaces feature id (http://xml.org/sax/features/namespaces).
protected static final String
VALIDATION_FEATURE_ID
Validation feature id (http://xml.org/sax/features/validation).
protected static final String
SCHEMA_VALIDATION_FEATURE_ID
Schema validation feature id (http://apache.org/xml/features/validation/schema).
protected static final String
SCHEMA_FULL_CHECKING_FEATURE_ID
Schema full checking feature id (http://apache.org/xml/features/validation/schema-full-checking).
protected static final boolean
DEBUG_ND
Debug normalize document
protected static final boolean
DEBUG
Debug namespace fix up algorithm
protected static final boolean
DEBUG_EVENTS
Debug document handler events
protected static final String
PREFIX
prefix added by namespace fixup algorithm should follow a pattern "NS" + index
protected DOMConfigurationImpl
fConfiguration
protected CoreDocumentImpl
fDocument
protected final XMLAttributesProxy
fAttrProxy
protected final QName
fQName
protected RevalidationHandler
fValidationHandler
Validation handler represents validator instance.
protected XMLDTDValidator
fDTDValidator
protected SymbolTable
fSymbolTable
symbol table
protected DOMErrorHandler
fErrorHandler
error handler. may be null.
private final DOMErrorImpl
fError
Cached {@link DOMError} impl. The same object is re-used to report multiple errors.
protected boolean
fNamespaceValidation
protected boolean
fPSVI
protected final NamespaceContext
fNamespaceContext
The namespace context of this document: stores namespaces in scope
protected final NamespaceContext
fLocalNSBinder
Stores all namespace bindings on the current element
protected final Vector
fAttributeList
list of attributes
protected final DOMLocatorImpl
fLocator
DOM Locator - for namespace fixup algorithm
protected Node
fCurrentNode
for setting the PSVI
private QName
fAttrQName
final XMLString
fNormalizedValue
public static final RuntimeException
abort
If the user stops the process, this exception will be thrown.
public boolean
isWhitespace
public boolean
docTypeFound
Constructors Summary
public DOMNormalizer()

    
     
Methods Summary
protected final voidaddNamespaceDecl(java.lang.String prefix, java.lang.String uri, com.sun.org.apache.xerces.internal.dom.ElementImpl element)
Adds a namespace attribute or replaces the value of existing namespace attribute with the given prefix and value for URI. In case prefix is empty will add/update default namespace declaration.

param
prefix
param
uri
exception
IOException

        if (DEBUG) {
            System.out.println("[ns-fixup] addNamespaceDecl ["+prefix+"]");
        }
        if (prefix == XMLSymbols.EMPTY_STRING) {
            if (DEBUG) {
                System.out.println("=>add xmlns=\""+uri+"\" declaration");
            }
            element.setAttributeNS(NamespaceContext.XMLNS_URI, XMLSymbols.PREFIX_XMLNS, uri);
        } else {
            if (DEBUG) {
                System.out.println("=>add xmlns:"+prefix+"=\""+uri+"\" declaration");
            }
            element.setAttributeNS(NamespaceContext.XMLNS_URI, "xmlns:"+prefix, uri);
        }
    
public voidcharacters(com.sun.org.apache.xerces.internal.xni.XMLString text, com.sun.org.apache.xerces.internal.xni.Augmentations augs)
Character content.

param
text The content.
param
augs Additional information that may include infoset augmentations
exception
XNIException Thrown by handler to signal an error.

    
public voidcomment(com.sun.org.apache.xerces.internal.xni.XMLString text, com.sun.org.apache.xerces.internal.xni.Augmentations augs)
A comment.

param
text The text in the comment.
param
augs Additional information that may include infoset augmentations
exception
XNIException Thrown by application to signal an error.

    
public voiddoctypeDecl(java.lang.String rootElement, java.lang.String publicId, java.lang.String systemId, com.sun.org.apache.xerces.internal.xni.Augmentations augs)
Notifies of the presence of the DOCTYPE line in the document.

param
rootElement The name of the root element.
param
publicId The public identifier if an external DTD or null if the external DTD is specified using SYSTEM.
param
systemId The system identifier if an external DTD, null otherwise.
param
augs Additional information that may include infoset augmentations
exception
XNIException Thrown by handler to signal an error.

    
public voidemptyElement(com.sun.org.apache.xerces.internal.xni.QName element, com.sun.org.apache.xerces.internal.xni.XMLAttributes attributes, com.sun.org.apache.xerces.internal.xni.Augmentations augs)
An empty element.

param
element The name of the element.
param
attributes The element attributes.
param
augs Additional information that may include infoset augmentations
exception
XNIException Thrown by handler to signal an error.

        if (DEBUG_EVENTS) {
            System.out.println("==>emptyElement: " +element);
        }
		if(true)
			return;
        
        startElement(element, attributes, augs);
        endElement(element, augs);
    
public voidendCDATA(com.sun.org.apache.xerces.internal.xni.Augmentations augs)
The end of a CDATA section.

param
augs Additional information that may include infoset augmentations
exception
XNIException Thrown by handler to signal an error.

    
public voidendDocument(com.sun.org.apache.xerces.internal.xni.Augmentations augs)
The end of the document.

param
augs Additional information that may include infoset augmentations
exception
XNIException Thrown by handler to signal an error.

    
public voidendElement(com.sun.org.apache.xerces.internal.xni.QName element, com.sun.org.apache.xerces.internal.xni.Augmentations augs)
The end of an element.

param
element The name of the element.
param
augs Additional information that may include infoset augmentations
exception
XNIException Thrown by handler to signal an error.

        if (DEBUG_EVENTS) {
            System.out.println("==>endElement: " + element);
        }
       	if(augs == null)
			return;
        ElementPSVI elementPSVI = (ElementPSVI) augs.getItem(Constants.ELEMENT_PSVI);
        if (elementPSVI != null) {
            ElementImpl elementNode = (ElementImpl) fCurrentNode;
            if (fPSVI) {
                ((PSVIElementNSImpl) fCurrentNode).setPSVI(elementPSVI);
            }
            // include element default content (if one is available)
            String normalizedValue = elementPSVI.getSchemaNormalizedValue();
            if ((fConfiguration.features & DOMConfigurationImpl.DTNORMALIZATION) != 0) {
                if (normalizedValue !=null)
                    elementNode.setTextContent(normalizedValue);
            }
            else {
                // NOTE: this is a hack: it is possible that DOM had an empty element
                // and validator sent default value using characters(), which we don't
                // implement. Thus, here we attempt to add the default value.
                String text = elementNode.getTextContent();
                if (text.length() == 0) {
                    // default content could be provided
                    if (normalizedValue !=null)
                        elementNode.setTextContent(normalizedValue);
                }
            }
        }
    
public voidendGeneralEntity(java.lang.String name, com.sun.org.apache.xerces.internal.xni.Augmentations augs)
This method notifies the end of a general entity.

Note: This method is not called for entity references appearing as part of attribute values.

param
name The name of the entity.
param
augs Additional information that may include infoset augmentations
exception
XNIException Thrown by handler to signal an error.

    
protected final voidexpandEntityRef(org.w3c.dom.Node parent, org.w3c.dom.Node reference)

        Node kid, next;
        for (kid = reference.getFirstChild(); kid != null; kid = next) {
            next = kid.getNextSibling();
            parent.insertBefore(kid, reference);
        }
    
public com.sun.org.apache.xerces.internal.xni.parser.XMLDocumentSourcegetDocumentSource()
Returns the document source.

        return null;
    
public com.sun.org.apache.xerces.internal.util.XMLGrammarPoolImplgetGrammarPool(java.lang.String systemId, java.lang.String internalSubset)

        try{
           
			XMLGrammarPreparser preparser = new XMLGrammarPreparser(fSymbolTable);
            XMLGrammarPoolImpl grammarPool = new XMLGrammarPoolImpl();
            preparser.registerPreparser(XMLGrammarDescription.XML_DTD, null);
            preparser.setProperty(GRAMMAR_POOL, grammarPool);
            preparser.setFeature(NAMESPACES_FEATURE_ID, true);
            preparser.setFeature(VALIDATION_FEATURE_ID, true);
		
			Grammar g = null;
		
			if(systemId != null){
				g = preparser.preparseGrammar(XMLGrammarDescription.XML_DTD,new XMLInputSource(null, systemId, null));
			}
		
			if(internalSubset != null && !internalSubset.equals("")){
				XMLInputSource xs = new XMLInputSource(null,systemId,null);
				xs.setCharacterStream(new StringReader(internalSubset));
				g = preparser.preparseGrammar(XMLGrammarDescription.XML_DTD,xs);
			}
			return grammarPool;
        }catch(Exception ex){
			if(DEBUG_ND)
				ex.printStackTrace();
        }
		return null;
    
public voidignorableWhitespace(com.sun.org.apache.xerces.internal.xni.XMLString text, com.sun.org.apache.xerces.internal.xni.Augmentations augs)
Ignorable whitespace. For this method to be called, the document source must have some way of determining that the text containing only whitespace characters should be considered ignorable. For example, the validator can determine if a length of whitespace characters in the document are ignorable based on the element content model.

param
text The ignorable whitespace.
param
augs Additional information that may include infoset augmentations
exception
XNIException Thrown by handler to signal an error.

		if(docTypeFound){
			isWhitespace = true;
		}
    
public static final voidisAttrValueWF(org.w3c.dom.DOMErrorHandler errorHandler, com.sun.org.apache.xerces.internal.dom.DOMErrorImpl error, com.sun.org.apache.xerces.internal.dom.DOMLocatorImpl locator, com.sun.org.apache.xerces.internal.dom.AttributeMap attributes, com.sun.org.apache.xerces.internal.dom.AttrImpl a, java.lang.String value, boolean xml11Version)
NON-DOM: check if attribute value is well-formed

param
attributes
param
a
param
value

        if (a.hasStringValue()) {
            isXMLCharWF(errorHandler, error, locator, value, xml11Version);
        } else {
            NodeList children = a.getChildNodes();
            //check each child node of the attribute's value
            for (int j = 0; j < children.getLength(); j++) {
                Node child = children.item(j);
                //If the attribute's child is an entity refernce
                if (child.getNodeType() == Node.ENTITY_REFERENCE_NODE) {
                    Document owner = a.getOwnerDocument();
                    Entity ent = null;
                    //search for the entity in the docType
                    //of the attribute's ownerDocument
                    if (owner != null) {
                        DocumentType docType = owner.getDoctype();
                        if (docType != null) {
                            NamedNodeMap entities = docType.getEntities();
                            ent = (Entity) entities.getNamedItemNS(
                            "*",
                            child.getNodeName());
                        }
                    }
                    //If the entity was not found issue a fatal error
                    if (ent == null) {
                        String msg = DOMMessageFormatter.formatMessage(
                            DOMMessageFormatter.DOM_DOMAIN, "UndeclaredEntRefInAttrValue", 
                            new Object[]{a.getNodeName()});
                        reportDOMError(errorHandler, error, locator, msg, DOMError.SEVERITY_ERROR, 
                            "UndeclaredEntRefInAttrValue");
                    }
                }
                else {
                    // Text node
                    isXMLCharWF(errorHandler, error, locator, child.getNodeValue(), xml11Version);
                }
            }
        }
    
public static final voidisCDataWF(org.w3c.dom.DOMErrorHandler errorHandler, com.sun.org.apache.xerces.internal.dom.DOMErrorImpl error, com.sun.org.apache.xerces.internal.dom.DOMLocatorImpl locator, java.lang.String datavalue, boolean isXML11Version)
Check if CDATA section is well-formed

param
datavalue
param
isXML11Version = true if XML 1.1

        if(datavalue == null || (datavalue.length() == 0) ) return ;
        
        char [] dataarray = datavalue.toCharArray();
        int datalength = dataarray.length ;
        
        //version of the document is XML 1.1
        if(isXML11Version){
            //we need to check all chracters as per production rules of XML11
            int i = 0 ;
            while(i < datalength){
                char c = dataarray[i++];
                if(XML11Char.isXML11Invalid(c)){
                    String msg =
                    DOMMessageFormatter.formatMessage(
                    DOMMessageFormatter.XML_DOMAIN,
                    "InvalidCharInCDSect",
                    new Object[] { Integer.toString(c, 16)});
                    reportDOMError(
                        errorHandler,
                        error,
                        locator,
                        msg,
                        DOMError.SEVERITY_ERROR,
                        "wf-invalid-character");
                }
                else if (c==']"){
                    int count = i;
                    if (count<datalength && dataarray[count]==']"){
                        while (++count <datalength && dataarray[count]==']"){
                            // do nothing
                        }
                        if (count <datalength && dataarray[count]=='>"){
                            //CDEndInContent
		  					String msg = DOMMessageFormatter.formatMessage(DOMMessageFormatter.XML_DOMAIN,
							    "CDEndInContent", null);
							reportDOMError(errorHandler, error, locator,msg, DOMError.SEVERITY_ERROR, "wf-invalid-character");
                        }
                    }
                    
                }
            }
        }//version of the document is XML 1.0
        else{
            //we need to check all chracters as per production rules of XML 1.0
            int i = 0 ;
            while(i < datalength){
                char c = dataarray[i++];
                if( XMLChar.isInvalid(c) ){
                	//Note:  The key InvalidCharInCDSect from XMLMessages.properties
                	//is being used to obtain the message and DOM error type
                	//"wf-invalid-character" is used.  Also per DOM it is error but 
                	//as per XML spec. it is fatal error
					String msg = DOMMessageFormatter.formatMessage(DOMMessageFormatter.XML_DOMAIN, "InvalidCharInCDSect", new Object[]{Integer.toString(c, 16)});
					reportDOMError(errorHandler, error, locator, msg, DOMError.SEVERITY_ERROR, 
					    "wf-invalid-character");
                }
                else if (c==']"){
                    int count = i;
                    if (count<datalength && dataarray[count]==']"){
                        while (++count <datalength && dataarray[count]==']"){
                            // do nothing
                        }
                        if (count <datalength && dataarray[count]=='>"){
		  					String msg = DOMMessageFormatter.formatMessage(DOMMessageFormatter.XML_DOMAIN,"CDEndInContent", null);
							reportDOMError(errorHandler, error, locator,  msg, DOMError.SEVERITY_ERROR, "wf-invalid-character");
                        }
                    }
                    
                }
            }
        }//end-else fDocument.isXMLVersion()
        
    
public static final voidisCommentWF(org.w3c.dom.DOMErrorHandler errorHandler, com.sun.org.apache.xerces.internal.dom.DOMErrorImpl error, com.sun.org.apache.xerces.internal.dom.DOMLocatorImpl locator, java.lang.String datavalue, boolean isXML11Version)
NON-DOM: check if value of the comment is well-formed

param
datavalue
param
isXML11Version = true if XML 1.1

        if(datavalue == null || (datavalue.length() == 0) ) return ;
        
        char [] dataarray = datavalue.toCharArray();
        int datalength = dataarray.length ;
        
        //version of the document is XML 1.1
        if(isXML11Version){
            //we need to check all chracters as per production rules of XML11
            int i = 0 ;
            while(i < datalength){
                char c = dataarray[i++];
                
                if(XML11Char.isXML11Invalid(c)){
  					String msg = DOMMessageFormatter.formatMessage(DOMMessageFormatter.XML_DOMAIN, 
					    "InvalidCharInComment", 
					    new Object [] {Integer.toString(dataarray[i-1], 16)});
					reportDOMError(errorHandler, error, locator, msg, DOMError.SEVERITY_ERROR, "wf-invalid-character");
                }
                else if (c == '-" && i<datalength && dataarray[i]=='-"){
  					String msg = DOMMessageFormatter.formatMessage(DOMMessageFormatter.XML_DOMAIN,
					    "DashDashInComment", null);
					// invalid: '--' in comment                   
					reportDOMError(errorHandler, error, locator, msg, DOMError.SEVERITY_ERROR, "wf-invalid-character");
                }
            }
        }//version of the document is XML 1.0
        else{
            //we need to check all chracters as per production rules of XML 1.0
            int i = 0 ;
            while(i < datalength){
                char c = dataarray[i++];
                if( XMLChar.isInvalid(c) ){
  					String msg = DOMMessageFormatter.formatMessage(DOMMessageFormatter.XML_DOMAIN,
					    "InvalidCharInComment", new Object [] {Integer.toString(dataarray[i-1], 16)});
					reportDOMError(errorHandler, error, locator, msg, DOMError.SEVERITY_ERROR, "wf-invalid-character");
                }  
                else if (c == '-" && i<datalength && dataarray[i]=='-"){
  					String msg = DOMMessageFormatter.formatMessage(DOMMessageFormatter.XML_DOMAIN,
					    "DashDashInComment", null);
					// invalid: '--' in comment                   
					reportDOMError(errorHandler, error, locator, msg, DOMError.SEVERITY_ERROR, "wf-invalid-character");
                }                                      
            }
            
        }//end-else fDocument.isXMLVersion()
        
    
public static final voidisXMLCharWF(org.w3c.dom.DOMErrorHandler errorHandler, com.sun.org.apache.xerces.internal.dom.DOMErrorImpl error, com.sun.org.apache.xerces.internal.dom.DOMLocatorImpl locator, java.lang.String datavalue, boolean isXML11Version)
NON-DOM: check for valid XML characters as per the XML version

param
datavalue
param
isXML11Version = true if XML 1.1

        if(datavalue == null || (datavalue.length() == 0) ) return ;
        char [] dataarray = datavalue.toCharArray();
        int datalength = dataarray.length ;
        
        //version of the document is XML 1.1
        if(isXML11Version){                    
            //we need to check all characters as per production rules of XML11
            int i = 0 ;
            while(i < datalength){
                if(XML11Char.isXML11Invalid(dataarray[i++])){
					String msg = DOMMessageFormatter.formatMessage(
                        DOMMessageFormatter.DOM_DOMAIN, "InvalidXMLCharInDOM", 
                        new Object[]{Integer.toString(dataarray[i-1], 16)});
					reportDOMError(errorHandler, error, locator, msg, DOMError.SEVERITY_ERROR, 
					    "wf-invalid-character");
                };
            }
        }//version of the document is XML 1.0
        else{                    
            //we need to check all characters as per production rules of XML 1.0
            int i = 0 ;
            while(i < datalength){
                if( XMLChar.isInvalid(dataarray[i++]) ){
					String msg = DOMMessageFormatter.formatMessage(
                        DOMMessageFormatter.DOM_DOMAIN, "InvalidXMLCharInDOM", 
                        new Object[]{Integer.toString(dataarray[i-1], 16)});
					reportDOMError(errorHandler, error, locator, msg, DOMError.SEVERITY_ERROR, 
					    "wf-invalid-character");
                };
            }
        }//end-else fDocument.isXMLVersion()
        
    
protected final voidnamespaceFixUp(com.sun.org.apache.xerces.internal.dom.ElementImpl element, com.sun.org.apache.xerces.internal.dom.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, name, uri, prefix;
        if (attributes != null) {
            
            // Record all valid local declarations
            for (int k=0; k < attributes.getLength(); k++) {
                Attr attr = (Attr)attributes.getItem(k);
                
                //do the name check only when version of the document was changed &
                //application has set the value of well-formed features to true
                if ( ((fConfiguration.features & DOMConfigurationImpl.WELLFORMED) != 0) &&
                fDocument.isXMLVersionChanged()){
                    //checkQName does checking based on the version of the document
                    fDocument.checkQName(attr.getPrefix() , attr.getLocalName()) ;
                }
                
                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 (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);
                            //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, XMLSymbols.EMPTY_STRING);
                    fNamespaceContext.declarePrefix(XMLSymbols.EMPTY_STRING, XMLSymbols.EMPTY_STRING);
                }
            }
        }
        
        // -----------------------------------------
        // 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.elementAt(i);
                fLocator.fRelatedNode = attr;

                if (DEBUG) {
                    System.out.println("==>[ns-fixup] process attribute: "+attr.getNodeName());
                }
                // normalize attribute value
                attr.normalize();
                value = attr.getValue();
                name = attr.getNodeName();
                uri = attr.getNamespaceURI();
                
                // make sure that value is never null.
                if (value == null) {
                    value=XMLSymbols.EMPTY_STRING;
                }
                
                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;
                    }
                    //---------------------------------------
                    // check if value of the attribute is namespace well-formed
                    //---------------------------------------
                    if ( ((fConfiguration.features & DOMConfigurationImpl.WELLFORMED) != 0)){
                            isAttrValueWF(fErrorHandler, fError, fLocator, attributes, (AttrImpl)attr, attr.getValue(), fDocument.isXML11Version());
                            if (fDocument.isXMLVersionChanged()){                                   
                                boolean wellformed=CoreDocumentImpl.isXMLName(attr.getNodeName() , fDocument.isXML11Version());
                                if (!wellformed){
				                        String msg = DOMMessageFormatter.formatMessage(
				                            DOMMessageFormatter.DOM_DOMAIN, 
				                            "wf-invalid-character-in-node-name", 
				                            new Object[]{"Attribute", attr.getNodeName()});
                                        reportDOMError(fErrorHandler, fError, fLocator, msg, DOMError.SEVERITY_ERROR, "wf-invalid-character-in-node-name");  
                                }
                        }
                    }
                    
                    // ---------------------------------------
                    // 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
                        
                        name  = attr.getNodeName();
                        // 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
    
final java.lang.StringnormalizeAttributeValue(java.lang.String value, org.w3c.dom.Attr attr)

        if (!attr.getSpecified()){
            // specified attributes should already have a normalized form
            // since those were added by validator
            return value;
        }
        int end = value.length();
        // ensure capacity
        if (fNormalizedValue.ch.length < end) {
            fNormalizedValue.ch = new char[end];
        }
        fNormalizedValue.length = 0;
        boolean normalized = false;
        for (int i = 0; i < end; i++) {
            char c = value.charAt(i);
            if (c==0x0009 || c==0x000A) {
                fNormalizedValue.ch[fNormalizedValue.length++] = ' ";
                normalized = true;
            }
            else if(c==0x000D){
                normalized = true;
                fNormalizedValue.ch[fNormalizedValue.length++] = ' ";
                int next = i+1;
                if (next < end && value.charAt(next)==0x000A) i=next; // skip following xA
            }
            else {
                fNormalizedValue.ch[fNormalizedValue.length++] = c;
            }
        }
        if (normalized){
            value = fNormalizedValue.toString();
            attr.setValue(value);
        }
        return value;
    
protected voidnormalizeDocument(com.sun.org.apache.xerces.internal.dom.CoreDocumentImpl document, com.sun.org.apache.xerces.internal.dom.DOMConfigurationImpl config)
Normalizes document. Note: reset() must be called before this method.

        
        fDocument = document;
        fConfiguration = config;
        
        // intialize and reset DOMNormalizer component
        //
        fSymbolTable = (SymbolTable) fConfiguration.getProperty(DOMConfigurationImpl.SYMBOL_TABLE);
        // reset namespace context
        fNamespaceContext.reset();
        fNamespaceContext.declarePrefix(XMLSymbols.EMPTY_STRING, XMLSymbols.EMPTY_STRING);
        docTypeFound = false; 
        if ((fConfiguration.features & DOMConfigurationImpl.VALIDATE) != 0) {
			String type =(String) fConfiguration.getProperty(fConfiguration.JAXP_SCHEMA_LANGUAGE);
			if(type != null && type.equals(Constants.NS_XMLSCHEMA))
				fValidationHandler = CoreDOMImplementationImpl.singleton.getValidator(XMLGrammarDescription.XML_SCHEMA);
            fConfiguration.setFeature(DOMConfigurationImpl.XERCES_VALIDATION, true);
            fConfiguration.setFeature(DOMConfigurationImpl.SCHEMA, true);
            // report fatal error on DOM Level 1 nodes
            fNamespaceValidation = true;
            
            // check if we need to fill in PSVI
            fPSVI = ((fConfiguration.features & DOMConfigurationImpl.PSVI) !=0)?true:false;
            
            // reset ID table
            fDocument.clearIdentifiers();
            
            // reset schema validator
            if(fValidationHandler!=null)
                ((XMLComponent) fValidationHandler).reset(fConfiguration);
            
        }
        
        fErrorHandler = (DOMErrorHandler) fConfiguration.getParameter(Constants.DOM_ERROR_HANDLER);
        if (fValidationHandler != null) {
            fValidationHandler.setDocumentHandler(this);
            fValidationHandler.startDocument( new SimpleLocator(fDocument.fDocumentURI, fDocument.fDocumentURI, -1, -1 ), fDocument.encoding, fNamespaceContext, null);
            
        }
        try {
            Node kid, next;
            for (kid = fDocument.getFirstChild(); kid != null; kid = next) {
                next = kid.getNextSibling();
                kid = normalizeNode(kid);
                if (kid != null) { // don't advance
                    next = kid;
                }
            }
            
            // release resources
            if (fValidationHandler != null) {
                fValidationHandler.endDocument(null);
                CoreDOMImplementationImpl.singleton.releaseValidator(
                XMLGrammarDescription.XML_SCHEMA, fValidationHandler);
                fValidationHandler = null;
            }
        }
        catch (RuntimeException e) {
			if(DEBUG_ND) e.printStackTrace();
            if( e==abort )
                return; // processing aborted by the user
            throw e;    // otherwise re-throw.
        }
        
    
protected org.w3c.dom.NodenormalizeNode(org.w3c.dom.Node node)
This method acts as if the document was going through a save and load cycle, putting the document in a "normal" form. The actual result depends on the features being set and governing what operations actually take place. See setNormalizationFeature for details. Noticeably this method normalizes Text nodes, makes the document "namespace wellformed", according to the algorithm described below in pseudo code, by adding missing namespace declaration attributes and adding or changing namespace prefixes, updates the replacement tree of EntityReference nodes,normalizes attribute values, etc.

param
node Modified node or null. If node is returned, we need to normalize again starting on the node returned.
return
the normalized Node

        
        int type = node.getNodeType();
        boolean wellformed;
        fLocator.fRelatedNode=node;
        
        switch (type) {
            case Node.DOCUMENT_TYPE_NODE: {
                if (DEBUG_ND) {
                    System.out.println("==>normalizeNode:{doctype}");
                }
            	fDTDValidator =(XMLDTDValidator) CoreDOMImplementationImpl.singleton.getDTDValidator();
                DocumentTypeImpl docNode = (DocumentTypeImpl)node;
                if(fDTDValidator != null){
				//fix me : 
            	fConfiguration.setFeature(DOMConfigurationImpl.XERCES_VALIDATION, false);
				
				fDTDValidator.startDocument( new SimpleLocator(fDocument.fDocumentURI, fDocument.fDocumentURI, -1, -1 ), fDocument.encoding, fNamespaceContext, null);
            
				
                if (DEBUG_ND) 
					System.out.println("Internal subset is "+docNode.getInternalSubset());
                XMLGrammarPoolImpl grammarPool = getGrammarPool(docNode.getSystemId(),docNode.getInternalSubset());
                fConfiguration.setProperty(GRAMMAR_POOL, grammarPool);        
            	fDTDValidator.setDocumentHandler(this);
                 ((XMLComponent) fDTDValidator).reset(fConfiguration);
				fDTDValidator.doctypeDecl(docNode.getName(),docNode.getPublicId(),docNode.getSystemId(),null);
				 docTypeFound = true;
                }
                //REVISIT: well-formness encoding info
                break;
            }
            
            case Node.ELEMENT_NODE: {
                if (DEBUG_ND) {
                    System.out.println("==>normalizeNode:{element} "+node.getNodeName());
                }
                
                //do the name check only when version of the document was changed &
                //application has set the value of well-formed features to true
                if ( ((fConfiguration.features & DOMConfigurationImpl.WELLFORMED) != 0) &&
                fDocument.isXMLVersionChanged()){
                    if(fNamespaceValidation){
                        wellformed = CoreDocumentImpl.isValidQName(node.getPrefix() , node.getLocalName(),  fDocument.isXML11Version()) ;
                    }
                    else{
                        wellformed = CoreDocumentImpl.isXMLName(node.getNodeName() , fDocument.isXML11Version());
                    }
                    if (!wellformed){
				            String msg = DOMMessageFormatter.formatMessage(
				                DOMMessageFormatter.DOM_DOMAIN, 
				                "wf-invalid-character-in-node-name", 
				                new Object[]{"Element", node.getNodeName()});
                            reportDOMError(fErrorHandler, fError, fLocator, msg, DOMError.SEVERITY_ERROR, 
                                "wf-invalid-character-in-node-name");                       
                    }
                }
                // push namespace context
                fNamespaceContext.pushContext();
                fLocalNSBinder.reset();
                
                ElementImpl elem = (ElementImpl)node;
                if (elem.needsSyncChildren()) {
                    elem.synchronizeChildren();
                }
                AttributeMap attributes = (elem.hasAttributes()) ? (AttributeMap) elem.getAttributes() : null;
                
                // fix namespaces and remove default attributes
                if ((fConfiguration.features & DOMConfigurationImpl.NAMESPACES) !=0) {
                    // fix namespaces
                    // normalize attribute values
                    // remove default attributes
                    namespaceFixUp(elem, attributes);
                } else {
                    if ( attributes!=null ) {
                        for ( int i=0; i<attributes.getLength(); ++i ) {
                            Attr attr = (Attr)attributes.item(i);
                            //removeDefault(attr, attributes);
                            attr.normalize();
                            if ( ((fConfiguration.features & DOMConfigurationImpl.WELLFORMED) != 0)){
                                isAttrValueWF(fErrorHandler, fError, fLocator, attributes, (AttrImpl)attr, attr.getValue(), fDocument.isXML11Version());
                                if (fDocument.isXMLVersionChanged()){
                                    wellformed=CoreDocumentImpl.isXMLName(node.getNodeName() , fDocument.isXML11Version());
                                    if (!wellformed){
				                            String msg = DOMMessageFormatter.formatMessage(
				                              DOMMessageFormatter.DOM_DOMAIN, 
				                              "wf-invalid-character-in-node-name", 
				                               new Object[]{"Attr",node.getNodeName()});
				                            reportDOMError(fErrorHandler, fError, fLocator, msg, DOMError.SEVERITY_ERROR, 
				                                "wf-invalid-character-in-node-name");
                                    }
                                }
                            }
                        }
                    }
                }
                
                
                if (fValidationHandler != null) {
                    // REVISIT: possible solutions to discard default content are:
                    //         either we pass some flag to XML Schema validator
                    //         or rely on the PSVI information.
                    fAttrProxy.setAttributes(attributes, fDocument, elem);
                    updateQName(elem, fQName); // updates global qname
                    // set error node in the dom error wrapper
                    // so if error occurs we can report an error node
                    fConfiguration.fErrorHandlerWrapper.fCurrentNode = node;
                    fCurrentNode = node;
                    // call re-validation handler
                    fValidationHandler.startElement(fQName, fAttrProxy, null);
                }
                
                if(fDTDValidator != null){
					if(attributes!=null)
                    fAttrProxy.setAttributes(attributes, fDocument, elem);
                    updateQName(elem, fQName); // updates global qname
                    fCurrentNode = node;
                    fDTDValidator.startElement(fQName, fAttrProxy, null);
                }
                
                // normalize children
                Node kid, next;
                for (kid = elem.getFirstChild(); kid != null; kid = next) {
                    next = kid.getNextSibling();
                    kid = normalizeNode(kid);
                    if (kid !=null) {
                        next = kid;  // don't advance
                    }
                }
                if (DEBUG_ND) {
                    // normalized subtree
                    System.out.println("***The children of {"+node.getNodeName()+"} are normalized");
                    for (kid = elem.getFirstChild(); kid != null; kid = next) {
                        next = kid.getNextSibling();
                        System.out.println(kid.getNodeName() +"["+kid.getNodeValue()+"]");
                    }
                    
                }
                
                
                if (fValidationHandler != null) {
                    updateQName(elem, fQName); // updates global qname
                    //
                    // set error node in the dom error wrapper
                    // so if error occurs we can report an error node
                    fConfiguration.fErrorHandlerWrapper.fCurrentNode = node;
                    fCurrentNode = node;
                    fValidationHandler.endElement(fQName, null);
                }
                if(fDTDValidator != null ){
                    updateQName(elem, fQName); // updates global qname
                    fCurrentNode = node;
                    fDTDValidator.endElement(fQName,null);
                }
                
                // pop namespace context
                fNamespaceContext.popContext();
                
                break;
            }
            
            case Node.COMMENT_NODE: {
                if (DEBUG_ND) {
                    System.out.println("==>normalizeNode:{comments}");
                }
                
                if ((fConfiguration.features & DOMConfigurationImpl.COMMENTS) == 0) {
                    Node prevSibling = node.getPreviousSibling();
                    Node parent = node.getParentNode();
                    // remove the comment node
                    parent.removeChild(node);
                    if (prevSibling != null && prevSibling.getNodeType() == Node.TEXT_NODE) {
                        Node nextSibling = prevSibling.getNextSibling();
                        if (nextSibling != null && nextSibling.getNodeType() == Node.TEXT_NODE) {
                            ((TextImpl)nextSibling).insertData(0, prevSibling.getNodeValue());
                            parent.removeChild(prevSibling);
                            return nextSibling;
                        }
                    }
                }//if comment node need not be removed
                else {
                    if ( ((fConfiguration.features & DOMConfigurationImpl.WELLFORMED) != 0)){
                        String commentdata = ((Comment)node).getData();
                        // check comments for invalid xml chracter as per the version
                        // of the document
                        isCommentWF(fErrorHandler, fError, fLocator, commentdata, fDocument.isXML11Version());
                    }
                }//end-else if comment node is not to be removed.
                break;
            }
            case Node.ENTITY_REFERENCE_NODE: {
                if (DEBUG_ND) {
                    System.out.println("==>normalizeNode:{entityRef} "+node.getNodeName());
                }
                
                if ((fConfiguration.features & DOMConfigurationImpl.ENTITIES) == 0) {
                    Node prevSibling = node.getPreviousSibling();
                    Node parent = node.getParentNode();
                    ((EntityReferenceImpl)node).setReadOnly(false, true);
                    expandEntityRef(parent, node);
                    parent.removeChild(node);
                    Node next = (prevSibling != null)?prevSibling.getNextSibling():parent.getFirstChild();
                    // The list of children #text -> &ent;
                    // and entity has a first child as a text
                    // we should not advance
                    if (prevSibling != null && next != null && prevSibling.getNodeType() == Node.TEXT_NODE && next.getNodeType() == Node.TEXT_NODE) {
                        return prevSibling;  // Don't advance                          
                    }
                    return next;
                } else {
                    if ( ((fConfiguration.features & DOMConfigurationImpl.WELLFORMED) != 0) &&
                    fDocument.isXMLVersionChanged()){
                        CoreDocumentImpl.isXMLName(node.getNodeName() , fDocument.isXML11Version());
                    }
                    // REVISIT: traverse entity reference and send appropriate calls to the validator
                    // (no normalization should be performed for the children).
                }
                break;
            }
            
            case Node.CDATA_SECTION_NODE: {
                if (DEBUG_ND) {
                    System.out.println("==>normalizeNode:{cdata}");
                }
                
                if ((fConfiguration.features & DOMConfigurationImpl.CDATA) == 0) {
                    // convert CDATA to TEXT nodes
                    Node prevSibling = node.getPreviousSibling();
                    if (prevSibling != null && prevSibling.getNodeType() == Node.TEXT_NODE){
                        ((Text)prevSibling).appendData(node.getNodeValue());
                        node.getParentNode().removeChild(node);
                        return prevSibling; //don't advance
                    }
                    else {
                        Text text = fDocument.createTextNode(node.getNodeValue());
                        Node parent = node.getParentNode();
                        node = parent.replaceChild(text, node);
                        return text;  //don't advance
                        
                    }
                }
                
                // send characters call for CDATA
                if (fValidationHandler != null) {
                    // set error node in the dom error wrapper
                    // so if error occurs we can report an error node
                    fConfiguration.fErrorHandlerWrapper.fCurrentNode = node;
                    fCurrentNode = node;
                    fValidationHandler.startCDATA(null);
                    fValidationHandler.characterData(node.getNodeValue(),null);
                    
                    fValidationHandler.endCDATA(null);
                }
                
                if(fDTDValidator != null){
                    fCurrentNode = node;
                    fDTDValidator.startCDATA(null);
                    String st = node.getNodeValue();
                    XMLString str = new XMLString();
                    if(st!=null)
                        str.setValues(st.toCharArray(),0,st.length());
                    fDTDValidator.characters(str, null);
                    fDTDValidator.endCDATA(null);
                }
                
                String value = node.getNodeValue();
                
                if ((fConfiguration.features & DOMConfigurationImpl.SPLITCDATA) != 0) {
                    int index;
                    Node parent = node.getParentNode();
                    
                    isXMLCharWF(fErrorHandler, fError, fLocator, node.getNodeValue(), fDocument.isXML11Version());
                    while ( (index=value.indexOf("]]>")) >= 0 ) {
                        node.setNodeValue(value.substring(0, index+2));
                        value = value.substring(index +2);
                        
                        Node firstSplitNode = node;
                        Node newChild = fDocument.createCDATASection(value);
                        parent.insertBefore(newChild, node.getNextSibling());
                        node = newChild;
                        // issue warning
                        fLocator.fRelatedNode = firstSplitNode;
                        String msg = DOMMessageFormatter.formatMessage(
                            DOMMessageFormatter.DOM_DOMAIN, 
                            "cdata-sections-splitted", 
                             null);
                        reportDOMError(fErrorHandler, fError, fLocator, msg, DOMError.SEVERITY_WARNING, 
                            "cdata-sections-splitted");
                    }
                    
                }
                else {
                    // check well-formness
                    isCDataWF(fErrorHandler, fError, fLocator, value, fDocument.isXML11Version());
                }
                break;
            }
            
            case Node.TEXT_NODE: {
                if (DEBUG_ND) {
                    System.out.println("==>normalizeNode(text):{"+node.getNodeValue()+"}");
                }
                // If node is a text node, we need to check for one of two
                // conditions:
                //   1) There is an adjacent text node
                //   2) There is no adjacent text node, but node is
                //      an empty text node.
                Node next = node.getNextSibling();
                // If an adjacent text node, merge it with this node
                if ( next!=null && next.getNodeType() == Node.TEXT_NODE ) {
                    ((Text)node).appendData(next.getNodeValue());
                    node.getParentNode().removeChild( next );
                    // We don't need to check well-formness here since we are not yet
                    // done with this node.
                    
                    return node; // Don't advance;
                } else if (node.getNodeValue().length()==0) {
                    // If kid is empty, remove it
                    node.getParentNode().removeChild( node );
                } else {
                    // validator.characters() call and well-formness
                    // Don't send characters or check well-formness in the following cases:
                    // 1. entities is false, next child is entity reference: expand tree first
                    // 2. comments is false, and next child is comment
                    // 3. cdata is false, and next child is cdata
                    
                    short nextType = (next != null)?next.getNodeType():-1;
                    if (nextType == -1 || !(((fConfiguration.features & DOMConfigurationImpl.ENTITIES) == 0 &&
                    nextType == Node.ENTITY_NODE) ||
                    ((fConfiguration.features & DOMConfigurationImpl.COMMENTS) == 0 &&
                    nextType == Node.COMMENT_NODE) ||
                    ((fConfiguration.features & DOMConfigurationImpl.CDATA) == 0) &&
                    nextType == Node.CDATA_SECTION_NODE)) {
                        if ( ((fConfiguration.features & DOMConfigurationImpl.WELLFORMED) != 0) ){
                            isXMLCharWF(fErrorHandler, fError, fLocator, node.getNodeValue(), fDocument.isXML11Version());
                        }
                        if (fValidationHandler != null) {
                            fConfiguration.fErrorHandlerWrapper.fCurrentNode = node;
                            fCurrentNode = node;
                            fValidationHandler.characterData(node.getNodeValue(), null);
                            if (DEBUG_ND) {
                                System.out.println("=====>characterData(),"+nextType);
                                
                            }
                        }
                        
                        if(fDTDValidator != null){
                            fCurrentNode = node;
                            String st = node.getNodeValue();
                            XMLString str = new XMLString();
                            if(st!=null)
                                str.setValues(st.toCharArray(),0,st.length());
                            fDTDValidator.characters(str, null);
							if(isWhitespace)
							((TextImpl)node).setIgnorableWhitespace(true);
                        }
                    }
                    else {
                        if (DEBUG_ND) {
                            System.out.println("=====>don't send characters(),"+nextType);
                            
                        }
                    }
                }
                break;
            }
            case Node.PROCESSING_INSTRUCTION_NODE: {
                
                //do the well-formed valid PI target name , data check when application has set the value of well-formed feature to true
                if((fConfiguration.features & DOMConfigurationImpl.WELLFORMED) != 0 ){
                    ProcessingInstruction pinode = (ProcessingInstruction)node ;
                    
                    String target = pinode.getTarget();
                    //1.check PI target name
                    if(fDocument.isXML11Version()){
                        wellformed = XML11Char.isXML11ValidName(target);
                    }
                    else{
                        wellformed = XMLChar.isValidName(target);
                    }
                    
                    if (!wellformed) {
                        String msg = DOMMessageFormatter.formatMessage(
                        DOMMessageFormatter.DOM_DOMAIN,
                        "wf-invalid-character-in-node-name",
                        new Object[]{"Element", node.getNodeName()});
						reportDOMError(fErrorHandler, fError, fLocator, msg, DOMError.SEVERITY_ERROR,  
                        "wf-invalid-character-in-node-name");
                    }
                    
                    //2. check PI data
                    //processing isntruction data may have certain characters
                    //which may not be valid XML character
                    isXMLCharWF(fErrorHandler, fError, fLocator, pinode.getData(), fDocument.isXML11Version());
                }
            }//end case Node.PROCESSING_INSTRUCTION_NODE
        
        }//end of switch
        return null;
    
public voidprocessingInstruction(java.lang.String target, com.sun.org.apache.xerces.internal.xni.XMLString data, com.sun.org.apache.xerces.internal.xni.Augmentations augs)
A processing instruction. Processing instructions consist of a target name and, optionally, text data. The data is only meaningful to the application.

Typically, a processing instruction's data will contain a series of pseudo-attributes. These pseudo-attributes follow the form of element attributes but are not parsed or presented to the application as anything other than text. The application is responsible for parsing the data.

param
target The target.
param
data The data or null if none specified.
param
augs Additional information that may include infoset augmentations
exception
XNIException Thrown by handler to signal an error.

    
public static final voidreportDOMError(org.w3c.dom.DOMErrorHandler errorHandler, com.sun.org.apache.xerces.internal.dom.DOMErrorImpl error, com.sun.org.apache.xerces.internal.dom.DOMLocatorImpl locator, java.lang.String message, short severity, java.lang.String type)
Reports a DOM error to the user handler. If the error is fatal, the processing will be always aborted.

        if( errorHandler!=null ) {
            error.reset();
            error.fMessage = message;
            error.fSeverity = severity;
            error.fLocator = locator;
            error.fType = type;
            error.fRelatedData = locator.fRelatedNode;
    
            if(!errorHandler.handleError(error))
                throw abort;
        }
        if( severity==DOMError.SEVERITY_FATAL_ERROR )
            throw abort;
    
public voidsetDocumentSource(com.sun.org.apache.xerces.internal.xni.parser.XMLDocumentSource source)
Sets the document source.

    
public voidstartCDATA(com.sun.org.apache.xerces.internal.xni.Augmentations augs)
The start of a CDATA section.

param
augs Additional information that may include infoset augmentations
exception
XNIException Thrown by handler to signal an error.

    
public voidstartDocument(com.sun.org.apache.xerces.internal.xni.XMLLocator locator, java.lang.String encoding, com.sun.org.apache.xerces.internal.xni.NamespaceContext namespaceContext, com.sun.org.apache.xerces.internal.xni.Augmentations augs)
The start of the document.

param
locator The document locator, or null if the document location cannot be reported during the parsing of this document. However, it is strongly recommended that a locator be supplied that can at least report the system identifier of the document.
param
encoding The auto-detected IANA encoding name of the entity stream. This value will be null in those situations where the entity encoding is not auto-detected (e.g. internal entities or a document entity that is parsed from a java.io.Reader).
param
namespaceContext The namespace context in effect at the start of this document. This object represents the current context. Implementors of this class are responsible for copying the namespace bindings from the the current context (and its parent contexts) if that information is important.
param
augs Additional information that may include infoset augmentations
exception
XNIException Thrown by handler to signal an error.

    
public voidstartElement(com.sun.org.apache.xerces.internal.xni.QName element, com.sun.org.apache.xerces.internal.xni.XMLAttributes attributes, com.sun.org.apache.xerces.internal.xni.Augmentations augs)
The start of an element.

param
element The name of the element.
param
attributes The element attributes.
param
augs Additional information that may include infoset augmentations
exception
XNIException Thrown by handler to signal an error.

        Element currentElement = (Element) fCurrentNode;
        int attrCount = attributes.getLength();
        if (DEBUG_EVENTS) {
            System.out.println("==>startElement: " +element+
            " attrs.length="+attrCount);
        }
        
        for (int i = 0; i < attrCount; i++) {
            attributes.getName(i, fAttrQName);
            Attr attr = null;
            
            attr = currentElement.getAttributeNodeNS(fAttrQName.uri, fAttrQName.localpart);
            AttributePSVI attrPSVI =
            (AttributePSVI) attributes.getAugmentations(i).getItem(Constants.ATTRIBUTE_PSVI);
            
            if (attrPSVI != null) {
                //REVISIT: instead we should be using augmentations:
                // to set/retrieve Id attributes
                XSTypeDefinition decl = attrPSVI.getMemberTypeDefinition();
                boolean id = false;
                if (decl != null){
                    id = ((XSSimpleType)decl).isIDType();
                } else{
                    decl = attrPSVI.getTypeDefinition();
                    if (decl !=null){
                        id = ((XSSimpleType)decl).isIDType();
                    }
                }
                if (id){
                    ((ElementImpl)currentElement).setIdAttributeNode(attr, true);
                }
                
                if (fPSVI) {
                    ((PSVIAttrNSImpl) attr).setPSVI(attrPSVI);
                }
                if ((fConfiguration.features & DOMConfigurationImpl.DTNORMALIZATION) != 0) {
                    // datatype-normalization
                    // NOTE: The specified value MUST be set after we set
                    //       the node value because that turns the "specified"
                    //       flag to "true" which may overwrite a "false"
                    //       value from the attribute list.
                    boolean specified = attr.getSpecified();
                    attr.setValue(attrPSVI.getSchemaNormalizedValue());
                    if (!specified) {
                        ((AttrImpl) attr).setSpecified(specified);
                    }
                }
            }
        }
    
public voidstartGeneralEntity(java.lang.String name, com.sun.org.apache.xerces.internal.xni.XMLResourceIdentifier identifier, java.lang.String encoding, com.sun.org.apache.xerces.internal.xni.Augmentations augs)
This method notifies the start of a general entity.

Note: This method is not called for entity references appearing as part of attribute values.

param
name The name of the general entity.
param
identifier The resource identifier.
param
encoding The auto-detected IANA encoding name of the entity stream. This value will be null in those situations where the entity encoding is not auto-detected (e.g. internal entities or a document entity that is parsed from a java.io.Reader).
param
augs Additional information that may include infoset augmentations
exception
XNIException Thrown by handler to signal an error.

    
public voidtextDecl(java.lang.String version, java.lang.String encoding, com.sun.org.apache.xerces.internal.xni.Augmentations augs)
Notifies of the presence of a TextDecl line in an entity. If present, this method will be called immediately following the startEntity call.

Note: This method will never be called for the document entity; it is only called for external general entities referenced in document content.

Note: This method is not called for entity references appearing as part of attribute values.

param
version The XML version, or null if not specified.
param
encoding The IANA encoding name of the entity.
param
augs Additional information that may include infoset augmentations
exception
XNIException Thrown by handler to signal an error.

    
protected final voidupdateQName(org.w3c.dom.Node node, com.sun.org.apache.xerces.internal.xni.QName qname)

        
        String prefix    = node.getPrefix();
        String namespace = node.getNamespaceURI();
        String localName = node.getLocalName();
        // REVISIT: the symbols are added too often: start/endElement
        //          and in the namespaceFixup. Should reduce number of calls to symbol table.
        qname.prefix = (prefix!=null && prefix.length()!=0)?fSymbolTable.addSymbol(prefix):null;
        qname.localpart = (localName != null)?fSymbolTable.addSymbol(localName):null;
        qname.rawname = fSymbolTable.addSymbol(node.getNodeName());
        qname.uri =  (namespace != null)?fSymbolTable.addSymbol(namespace):null;
    
public voidxmlDecl(java.lang.String version, java.lang.String encoding, java.lang.String standalone, com.sun.org.apache.xerces.internal.xni.Augmentations augs)
Notifies of the presence of an XMLDecl line in the document. If present, this method will be called immediately following the startDocument call.

param
version The XML version.
param
encoding The IANA encoding name of the document, or null if not specified.
param
standalone The standalone value, or null if not specified.
param
augs Additional information that may include infoset augmentations
exception
XNIException Thrown by handler to signal an error.