Index: /home/ekuns/workspace/castor-4/src/tests/main/org/exolab/castor/tests/framework/xmldiff/xml/XMLContentHandler.java
===================================================================
--- /home/ekuns/workspace/castor-4/src/tests/main/org/exolab/castor/tests/framework/xmldiff/xml/XMLContentHandler.java	(revision 6734)
+++ /home/ekuns/workspace/castor-4/src/tests/main/org/exolab/castor/tests/framework/xmldiff/xml/XMLContentHandler.java	(working copy)
@@ -17,6 +17,9 @@
  */
 package org.exolab.castor.tests.framework.xmldiff.xml;
 
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.Map;
 import java.util.Stack;
 
 import org.exolab.castor.tests.framework.xmldiff.xml.nodes.Attribute;
@@ -49,6 +52,8 @@
     private Locator             _locator              = null;
     /** The current node to which we are adding content. */
     private ParentNode          _currentNode          = null;
+    /** Keeps track of all URL mapping prefixes currently defined.  */
+    private Map                 _prefixes             = new HashMap();
 
     /**
      * Creates a new XMLBuilder.
@@ -85,11 +90,12 @@
      * @param qName the qualified naem of the element
      * @throws org.xml.sax.SAXException if we have a mismatched end element tag
      */
-    public void endElement(String uri, String name, String qName) throws org.xml.sax.SAXException {
+    public void endElement(final String uri, final String name, final String qName)
+                                                   throws org.xml.sax.SAXException {
         final String localName = name;
 
-        final int idx = name.indexOf(':');
-        final String prefix = (idx >= 0) ? name.substring(0, idx) : "";
+        final int idx = qName.indexOf(':');
+        final String prefix = (idx >= 0) ? qName.substring(0, idx) : "";
 
         // Check the prefix to make sure it is appropriate
         String uriOfPrefix = _currentNode.getNamespaceURI(prefix);
@@ -96,7 +102,7 @@
         String uriOfElement = _currentNode.getNamespaceURI();
         if ((uriOfPrefix == null ^ uriOfElement == null)
                 || (uriOfPrefix != null && !uriOfPrefix.equals(uriOfElement))) {
-            throw new org.xml.sax.SAXException("In Element " + name + ", URI of prefix " + uriOfPrefix +
+            throw new org.xml.sax.SAXException("In Element " + qName + ", URI of prefix " + uriOfPrefix +
                                                " does not match URI of Element " + uriOfElement);
         }
 
@@ -117,7 +123,7 @@
      * @throws org.xml.sax.SAXException never
      */
     public void endPrefixMapping(final String prefix) throws SAXException {
-        // Nothing to do
+        _prefixes.remove(prefix);
     }
 
     /**
@@ -137,7 +143,7 @@
      * @throws org.xml.sax.SAXException never
      */
     public void ignorableWhitespace(final char[] chars, final int start, final int length)
-            throws org.xml.sax.SAXException {
+                                                  throws org.xml.sax.SAXException {
         // Deliberately ignore -- we don't care
     }
 
@@ -149,7 +155,7 @@
      * @throws org.xml.sax.SAXException never
      */
     public void processingInstruction(final String target, final String data)
-            throws org.xml.sax.SAXException {
+                                                  throws org.xml.sax.SAXException {
         ProcessingInstruction pi = new ProcessingInstruction(target, data);
         _currentNode.addChild(pi);
     }
@@ -159,7 +165,7 @@
      *
      * @param locator the Locator used by this DocumentHandler.
      */
-    public void setDocumentLocator(Locator locator) {
+    public void setDocumentLocator(final Locator locator) {
         _locator = locator;
     }
 
@@ -167,7 +173,7 @@
      * Gives notification about a skipped Entity during XML parsing.
      * @param name the name of the skipped entity.
      */
-    public void skippedEntity(String name) {
+    public void skippedEntity(final String name) {
         // Nothing to do
     }
 
@@ -189,7 +195,7 @@
      * @throws org.xml.sax.SAXException If we are not given an element name.
      */
     public void startElement(final String uri, final String name, final String qName, final Attributes atts) throws org.xml.sax.SAXException {
-        if (name == null) {
+        if (qName == null) {
             throw new SAXException("No Element name given");
         }
 
@@ -196,13 +202,13 @@
         final String prefix;
         final String localName;
 
-        int idx = name.indexOf(':');
+        int idx = qName.indexOf(':');
         if (idx >= 0) {
-            prefix = name.substring(0, idx);
-            localName = name.substring(idx + 1);
+            prefix = qName.substring(0, idx);
+            localName = qName.substring(idx + 1);
         } else {
             prefix = "";
-            localName = name;
+            localName = qName;
         }
 
         Element element = new Element(null, localName);
@@ -213,23 +219,23 @@
 
         _currentNode.addChild(element);
 
+        // Add all current namespaces to this element
+        for (Iterator i = _prefixes.entrySet().iterator(); i.hasNext(); ) {
+            Map.Entry me = (Map.Entry) i.next();
+            element.addNamespace(new Namespace((String)me.getKey(), (String) me.getValue()));
+        }
+
+        // Then add all attributes
         if (atts != null && atts.getLength() > 0) {
             for (int i = 0; i < atts.getLength(); i++) {
                 String attName = atts.getQName(i);
-                if (attName.equals("xmlns")) {
-                    element.addNamespace(new Namespace("", atts.getValue(i)));
-                } else if (attName.startsWith("xmlns:")) {
-                    String namespacePrefix = attName.substring(6);
-                    element.addNamespace(new Namespace(namespacePrefix, atts.getValue(i)));
-                } else {
-                    String ns = null;
-                    idx = attName.indexOf(':');
-                    if (idx > 0) {
-                        ns = element.getNamespaceURI(attName.substring(0, idx));
-                        attName = attName.substring(idx + 1);
-                    }
-                    element.addAttribute(new Attribute(ns, attName, atts.getValue(i)));
+                String ns = null;
+                idx = attName.indexOf(':');
+                if (idx > 0) {
+                    ns = element.getNamespaceURI(attName.substring(0, idx));
+                    attName = attName.substring(idx + 1);
                 }
+                element.addAttribute(new Attribute(ns, attName, atts.getValue(i)));
             }
         }
 
@@ -254,8 +260,8 @@
      * @param uri The namespace URI
      * @throws org.xml.sax.SAXException never
      */
-    public void startPrefixMapping(String prefix, String uri) {
-        // Nothing to do
+    public void startPrefixMapping(final String prefix, final String uri) {
+        _prefixes.put(prefix, uri);
     }
 
 }
Index: /home/ekuns/workspace/castor-4/src/tests/main/org/exolab/castor/tests/framework/xmldiff/XMLDiff.java
===================================================================
--- /home/ekuns/workspace/castor-4/src/tests/main/org/exolab/castor/tests/framework/xmldiff/XMLDiff.java	(revision 6734)
+++ /home/ekuns/workspace/castor-4/src/tests/main/org/exolab/castor/tests/framework/xmldiff/XMLDiff.java	(working copy)
@@ -40,6 +40,9 @@
  */
 public class XMLDiff {
 
+    /** The namespace of XML Schema. */
+    private static final String XMLSCHEMA_INSTANCE = "http://www.w3.org/2001/XMLSchema-instance";
+
     /** Filename of the 1st XML item being compared. */
     private final String      _file1;
     /** Filename of the 2nd XML item being compared. */
@@ -117,7 +120,7 @@
         if (!hasSameType(node1, node2)) {
             if (_print) {
                 _pw.println("Types differ: <" + node1.getLocalName() + "> and <"
-                            + node2.getLocalName() + ">");
+                            + node2.getLocalName() + "> for" + node1.getNodeLocation());
             }
             return 1;
         }
@@ -128,7 +131,8 @@
         String ns2 = node2.getNamespaceURI();
         if (!compareTextNullEqualsEmpty(ns1, ns2)) {
             if (_print) {
-                _pw.println("Namespaces differ: ('" + ns1 + "' != '" + ns2 + "').");
+                _pw.println("Namespaces differ: ('" + ns1 + "' != '" + ns2 + "') for "
+                            + node1.getNodeLocation());
             }
 
             ++diffCount;
@@ -140,7 +144,8 @@
 
         if (name1 == null && name2 != null) {
             if (_print) {
-                _pw.println("Names differ: null vs. <" + name2 + ">");
+                _pw.println("Names differ: null vs. <" + name2 + "> for "
+                            + node1.getNodeLocation());
             }
             ++diffCount;
             return diffCount;
@@ -146,7 +151,8 @@
             return diffCount;
         } else if (name2 == null && name1 != null) {
             if (_print) {
-                _pw.println("Names differ: <" + name1 + "> vs null");
+                _pw.println("Names differ: <" + name1 + "> vs null for "
+                            + node1.getNodeLocation());
             }
             ++diffCount;
             return diffCount;
@@ -152,7 +158,8 @@
             return diffCount;
         } else if (name1 != null && !name1.equals(name2)) {
             if (_print) {
-                _pw.println("Names differ: <" + name1 + "> != <" + name2 + ">");
+                _pw.println("Names differ: <" + name1 + "> != <" + name2 + "> for "
+                            + node1.getNodeLocation());
             }
             ++diffCount;
             return diffCount;
@@ -222,9 +229,15 @@
             // Does node2 have this attribute at all?
             String attValue2 = node2.getAttribute(attr1.getNamespaceURI(), attr1.getLocalName());
             if (attValue2 == null) {
+                // Is this an attribute that is allowed to be missing sometimes?
+                if (missingattributeIsIgnorable(attr1)) {
+                    continue;
+                }
+
+                // If not, complain
                 printElementChangeBlock(node1, node2, "Attribute '"
-                                        + attr1.getLocalName()
-                                        + "' does not exist in the second node.");
+                                        + attr1.getNodeLocation()
+                                        + "' does not exist in the second document.");
                 diffCount++;
                 continue;
             }
@@ -233,7 +246,7 @@
             String attValue1 = attr1.getStringValue();
             if (!compareTextLikeQName(node1, node2, attValue1, attValue2)) {
                 printElementChangeBlock(node1, node2, "Attribute '"
-                                        + attr1.getLocalName()
+                                        + attr1.getNodeLocation()
                                         + "' values are different.");
                 diffCount++;
             }
@@ -243,9 +256,15 @@
         for (Iterator i = node2.getAttributeIterator(); i.hasNext(); ) {
             Attribute attr2 = (Attribute) i.next();
             if (node1.getAttribute(attr2.getNamespaceURI(), attr2.getLocalName()) == null) {
+                // Is this an attribute that is allowed to be missing sometimes?
+                if (missingattributeIsIgnorable(attr2)) {
+                    continue;
+                }
+
+                // If not, complain
                 printElementChangeBlock(node1, node2, "Attribute '"
-                                        + attr2.getLocalName()
-                                        + "' does not exist in the first node.");
+                                        + attr2.getNodeLocation()
+                                        + "' does not exist in the first document.");
                 diffCount++;
             }
         }
@@ -253,6 +272,22 @@
         return diffCount;
     }
 
+    private boolean missingattributeIsIgnorable(Attribute attr) {
+        String name = attr.getLocalName();
+        String ns = attr.getNamespaceURI();
+        if (ns == null) {
+            ns = "";
+        }
+
+        if (name.equals("noNamespaceSchemaLocation") && ns.equals(XMLSCHEMA_INSTANCE)) {
+            return true;
+        }
+        if (name.equals("schemaLocation") && ns.equals(XMLSCHEMA_INSTANCE)) {
+            return true;
+        }
+        return false;
+    }
+
     /**
      * Compare the provided attribute text as if it were a QName.
      *
@@ -495,7 +530,8 @@
             }
         }
 
-        _pw.println("Missing child node: " + target.getNodeLocation());
+        _pw.println("Missing child node: " + target.getNodeLocation() + " for "
+                    + target.getNodeLocation());
         return 1;
     }
 

