Author: mukulg
Date: Fri Jan 19 14:22:31 2024
New Revision: 1915328

URL: http://svn.apache.org/viewvc?rev=1915328&view=rev
Log:
implementing for XML dom documents, method 'isEqualNodeWithQName' similar to 
'isEqualNode' to compare two XML elements, to support use cases like use of 
XPath 3.1 function fn:deep-equal.

Added:
    
xerces/java/branches/xml-schema-1.1-dev/src/org/apache/xerces/dom/NodeEqualityWithQname.java
   (with props)
Removed:
    
xerces/java/branches/xml-schema-1.1-dev/src/org/apache/xerces/dom/NodeImpl.java
Modified:
    
xerces/java/branches/xml-schema-1.1-dev/src/org/apache/xerces/dom/ElementImpl.java
    
xerces/java/branches/xml-schema-1.1-dev/src/org/apache/xerces/dom/ParentNode.java

Modified: 
xerces/java/branches/xml-schema-1.1-dev/src/org/apache/xerces/dom/ElementImpl.java
URL: 
http://svn.apache.org/viewvc/xerces/java/branches/xml-schema-1.1-dev/src/org/apache/xerces/dom/ElementImpl.java?rev=1915328&r1=1915327&r2=1915328&view=diff
==============================================================================
--- 
xerces/java/branches/xml-schema-1.1-dev/src/org/apache/xerces/dom/ElementImpl.java
 (original)
+++ 
xerces/java/branches/xml-schema-1.1-dev/src/org/apache/xerces/dom/ElementImpl.java
 Fri Jan 19 14:22:31 2024
@@ -17,6 +17,8 @@
 
 package org.apache.xerces.dom;
 
+import javax.xml.XMLConstants;
+
 import org.apache.xerces.util.URI;
 import org.w3c.dom.Attr;
 import org.w3c.dom.DOMException;
@@ -58,7 +60,7 @@ import org.w3c.dom.TypeInfo;
  */
 public class ElementImpl
     extends ParentNode
-    implements Element, ElementTraversal, TypeInfo {
+    implements Element, ElementTraversal, TypeInfo, NodeEqualityWithQname {
 
     //
     // Constants
@@ -934,6 +936,93 @@ public class ElementImpl
         }
         return true;
     }
+    
+    /**
+     * This method implementation is added, to support use
+     * cases like use of XPath 3.1 function fn:deep-equal.
+     */
+    public boolean isEqualNodeWithQName(Node arg) {
+        if (!super.isEqualNodeWithQName(arg)) {
+            return false;
+        }
+        
+        boolean hasAttrs = hasAttributes();
+        if (hasAttrs != ((Element) arg).hasAttributes()) {
+            return false;
+        }
+        
+        if (hasAttrs) {
+            NamedNodeMap map1 = getAttributes();
+            NamedNodeMap map2 = ((Element) arg).getAttributes();
+            
+            int len = map1.getLength();            
+            if (len != map2.getLength()) {
+                return false;
+            }
+            
+            boolean isNsDeclEqual = false;
+            
+            for (int i = 0; i < len; i++) {
+                Node n1 = map1.item(i);
+                if (n1.getLocalName() == null) { // DOM Level 1 Node
+                    Node n2 = map2.getNamedItem(n1.getNodeName());
+                    if (n2 == null || !((NodeImpl) n1).isEqualNode(n2)) {
+                        return false;
+                    }
+                }
+                else {                                        
+                    String nodeName1 = n1.getNodeName();                       
                 
+                    
+                    if ((XMLConstants.XMLNS_ATTRIBUTE.equals(nodeName1) || 
+                                                          
nodeName1.startsWith(XMLConstants.XMLNS_ATTRIBUTE + ":")) && 
+                                                          
XMLConstants.XMLNS_ATTRIBUTE_NS_URI.equals(n1.getNamespaceURI())) {             
           
+                        // This is an XML namespace declaration within the 
first element. 
+                        // We check whether, there's a logically equal XML 
namespace 
+                        // declaration present within the second element.
+                        
+                        // For two XML namespace declarations to be logically 
equal, 
+                        // the only requirement is to have their namespace 
uri's 
+                        // as equal.
+                        
+                        // Few examples of logically equal XML namespace 
declarations 
+                        // are following:
+                        // (xmlns="http://a";, xmlns="http://a";),
+                        // (xmlns="http://a";, xmlns:a1="http://a";),
+                        // (xmlns:a1="http://a";, xmlns="http://a";),
+                        // (xmlns:a1="http://a";, xmlns:b1="http://a";)          
                                      
+                        
+                        String nsDeclUri = n1.getNodeValue();
+                        int len2 = map2.getLength();
+                        for (int idx = 0; idx < len2; idx++) {
+                           Node attrNode2 = map2.item(idx);
+                           String nodeName2 = attrNode2.getNodeName();
+                           String nsDeclUri2 = attrNode2.getNodeValue();
+                           String nsUri2 = attrNode2.getNamespaceURI();
+                           if 
(XMLConstants.XMLNS_ATTRIBUTE_NS_URI.equals(nsUri2) && 
+                                                         
(XMLConstants.XMLNS_ATTRIBUTE.equals(nodeName2) || 
+                                                               
nodeName2.startsWith(XMLConstants.XMLNS_ATTRIBUTE + ":")) && 
+                                                               
nsDeclUri.equals(nsDeclUri2)) {
+                               isNsDeclEqual = true;
+                               break;
+                           }
+                        }
+                        
+                        if (isNsDeclEqual) {
+                           continue;  
+                        }
+                    }                    
+                    
+                    Node n2 = map2.getNamedItemNS(n1.getNamespaceURI(),
+                                                  n1.getLocalName());
+                    if (n2 == null || !((NodeImpl) 
n1).isEqualNodeWithQName(n2)) {
+                       return false;
+                    }
+                }
+            }
+        }
+        
+        return true; 
+    }
 
     /**
      * DOM Level 3: register the given attribute node as an ID attribute

Added: 
xerces/java/branches/xml-schema-1.1-dev/src/org/apache/xerces/dom/NodeEqualityWithQname.java
URL: 
http://svn.apache.org/viewvc/xerces/java/branches/xml-schema-1.1-dev/src/org/apache/xerces/dom/NodeEqualityWithQname.java?rev=1915328&view=auto
==============================================================================
--- 
xerces/java/branches/xml-schema-1.1-dev/src/org/apache/xerces/dom/NodeEqualityWithQname.java
 (added)
+++ 
xerces/java/branches/xml-schema-1.1-dev/src/org/apache/xerces/dom/NodeEqualityWithQname.java
 Fri Jan 19 14:22:31 2024
@@ -0,0 +1,37 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ * 
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.xerces.dom;
+
+import org.w3c.dom.Node;
+
+/**
+ * This interface provides support for checking equality 
+ * of two XML element nodes, where considering XML element 
+ * names by their QName values, to support use cases like
+ * XPath 3.1 function fn:deep-equal.
+ * 
+ * @xerces.internal
+ * 
+ * @author Mukul Gandhi <muk...@apache.org>
+ * 
+ * @version $Id$
+ */
+public interface NodeEqualityWithQname {
+    
+    public boolean isEqualNodeWithQName(Node arg);
+    
+}

Propchange: 
xerces/java/branches/xml-schema-1.1-dev/src/org/apache/xerces/dom/NodeEqualityWithQname.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: 
xerces/java/branches/xml-schema-1.1-dev/src/org/apache/xerces/dom/NodeEqualityWithQname.java
------------------------------------------------------------------------------
    svn:keywords = Author Date Id Revision

Modified: 
xerces/java/branches/xml-schema-1.1-dev/src/org/apache/xerces/dom/ParentNode.java
URL: 
http://svn.apache.org/viewvc/xerces/java/branches/xml-schema-1.1-dev/src/org/apache/xerces/dom/ParentNode.java?rev=1915328&r1=1915327&r2=1915328&view=diff
==============================================================================
--- 
xerces/java/branches/xml-schema-1.1-dev/src/org/apache/xerces/dom/ParentNode.java
 (original)
+++ 
xerces/java/branches/xml-schema-1.1-dev/src/org/apache/xerces/dom/ParentNode.java
 Fri Jan 19 14:22:31 2024
@@ -876,6 +876,43 @@ public abstract class ParentNode
         }
         return true;
     }
+    
+    /**
+     * This method implementation is added, to support use
+     * cases like use of XPath 3.1 function fn:deep-equal.
+     */
+    public boolean isEqualNodeWithQName(Node arg) {
+        if (!super.isEqualNodeWithQName(arg)) {
+            return false;
+        }
+        
+        // there are many ways to do this test, and there isn't any way
+        // better than another. Performance may vary greatly depending on
+        // the implementations involved. This one should work fine for us.
+        Node child1 = getFirstChild();
+        Node child2 = arg.getFirstChild();
+        
+        while (child1 != null && child2 != null) {
+            if ((child1 instanceof ElementImpl) && 
+                                             (child2 instanceof ElementImpl)) {
+                if (!((ElementImpl)child1).isEqualNodeWithQName((ElementImpl)
+                                                                           
child2)) {
+                    return false;
+                }  
+            }
+            else if (!child1.isEqualNode(child2)) {
+                return false;
+            }
+            child1 = child1.getNextSibling();
+            child2 = child2.getNextSibling();
+        }
+        
+        if (child1 != child2) {
+            return false;
+        }
+        
+        return true; 
+    }
 
     //
     // Public methods



---------------------------------------------------------------------
To unsubscribe, e-mail: commits-unsubscr...@xerces.apache.org
For additional commands, e-mail: commits-h...@xerces.apache.org

Reply via email to