in src/org/apache/xerces/dom/DOMNormalizer.java [295:691]
protected Node normalizeNode (Node 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}");
}
// REVISIT: well-formedness 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 (fDocument.errorChecking) {
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);
if ((fConfiguration.features & DOMConfigurationImpl.NSDECL) == 0) {
// Namespace declarations may have been added by namespace fix-up. Need
// to fetch the AttributeMap again if it contained no attributes prior
// to namespace fix-up.
if (attributes == null) {
attributes = (elem.hasAttributes()) ? (AttributeMap) elem.getAttributes() : null;
}
if (attributes != null) {
for (int i = 0; i < attributes.getLength(); ++i) {
Attr att = (Attr)attributes.getItem(i);
if (XMLSymbols.PREFIX_XMLNS.equals(att.getPrefix()) ||
XMLSymbols.PREFIX_XMLNS.equals(att.getName())) {
elem.removeAttributeNode(att);
--i;
}
}
}
}
} else {
if ( attributes!=null ) {
for ( int i=0; i<attributes.getLength(); ++i ) {
Attr attr = (Attr)attributes.item(i);
//removeDefault(attr, attributes);
attr.normalize();
if (fDocument.errorChecking && ((fConfiguration.features & DOMConfigurationImpl.WELLFORMED) != 0)){
isAttrValueWF(fErrorHandler, fError, fLocator, attributes, attr, attr.getValue(), fDocument.isXML11Version());
if (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[]{"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);
}
// 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);
}
// 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 (fDocument.errorChecking && ((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());
}
if (fValidationHandler != null) {
// Don't bother filling an XMLString with the text of the comment.
// We only send the comment event to the validator handler so that
// when the schema-type is DTD an error will be reported for a
// comment appearing in EMPTY content.
fValidationHandler.comment(EMPTY_STRING, null);
}
}//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 (fDocument.errorChecking && ((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);
}
String value = node.getNodeValue();
if ((fConfiguration.features & DOMConfigurationImpl.SPLITCDATA) != 0) {
int index;
Node parent = node.getParentNode();
if (fDocument.errorChecking) {
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 if (fDocument.errorChecking) {
// check well-formedness
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 (fDocument.errorChecking && ((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 (!fNamespaceValidation) {
if (fAllWhitespace) {
fAllWhitespace = false;
((TextImpl)node).setIgnorableWhitespace(true);
}
else {
((TextImpl)node).setIgnorableWhitespace(false);
}
}
if (DEBUG_ND) {
System.out.println("=====>characterData(),"+nextType);
}
}
}
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 (fDocument.errorChecking && (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());
}
if (fValidationHandler != null) {
// Don't bother filling an XMLString with the data section of the
// processing instruction. We only send the processing instruction
// event to the validator handler so that when the schema-type is
// DTD an error will be reported for a processing instruction
// appearing in EMPTY content.
fValidationHandler.processingInstruction(((ProcessingInstruction) node).getTarget(), EMPTY_STRING, null);
}
}//end case Node.PROCESSING_INSTRUCTION_NODE
}//end of switch
return null;
}//normalizeNode