Author: mukulg
Date: Fri Jan 19 14:19:44 2024
New Revision: 1915327
URL: http://svn.apache.org/viewvc?rev=1915327&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/trunk/src/org/apache/xerces/dom/NodeEqualityWithQname.java
(with props)
Modified:
xerces/java/trunk/src/org/apache/xerces/dom/ElementImpl.java
xerces/java/trunk/src/org/apache/xerces/dom/NodeImpl.java
xerces/java/trunk/src/org/apache/xerces/dom/ParentNode.java
Modified: xerces/java/trunk/src/org/apache/xerces/dom/ElementImpl.java
URL:
http://svn.apache.org/viewvc/xerces/java/trunk/src/org/apache/xerces/dom/ElementImpl.java?rev=1915327&r1=1915326&r2=1915327&view=diff
==============================================================================
--- xerces/java/trunk/src/org/apache/xerces/dom/ElementImpl.java (original)
+++ xerces/java/trunk/src/org/apache/xerces/dom/ElementImpl.java Fri Jan 19
14:19:44 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/trunk/src/org/apache/xerces/dom/NodeEqualityWithQname.java
URL:
http://svn.apache.org/viewvc/xerces/java/trunk/src/org/apache/xerces/dom/NodeEqualityWithQname.java?rev=1915327&view=auto
==============================================================================
--- xerces/java/trunk/src/org/apache/xerces/dom/NodeEqualityWithQname.java
(added)
+++ xerces/java/trunk/src/org/apache/xerces/dom/NodeEqualityWithQname.java Fri
Jan 19 14:19:44 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 <[email protected]>
+ *
+ * @version $Id$
+ */
+public interface NodeEqualityWithQname {
+
+ public boolean isEqualNodeWithQName(Node arg);
+
+}
Propchange:
xerces/java/trunk/src/org/apache/xerces/dom/NodeEqualityWithQname.java
------------------------------------------------------------------------------
svn:eol-style = native
Propchange:
xerces/java/trunk/src/org/apache/xerces/dom/NodeEqualityWithQname.java
------------------------------------------------------------------------------
svn:keywords = Author Date Id Revision
Modified: xerces/java/trunk/src/org/apache/xerces/dom/NodeImpl.java
URL:
http://svn.apache.org/viewvc/xerces/java/trunk/src/org/apache/xerces/dom/NodeImpl.java?rev=1915327&r1=1915326&r2=1915327&view=diff
==============================================================================
--- xerces/java/trunk/src/org/apache/xerces/dom/NodeImpl.java (original)
+++ xerces/java/trunk/src/org/apache/xerces/dom/NodeImpl.java Fri Jan 19
14:19:44 2024
@@ -80,7 +80,7 @@ import org.w3c.dom.events.EventTarget;
* @since PR-DOM-Level-1-19980818.
*/
public abstract class NodeImpl
- implements Node, NodeList, EventTarget, Cloneable, Serializable{
+ implements Node, NodeList, EventTarget, Cloneable, NodeEqualityWithQname,
Serializable{
//
// Constants
@@ -1752,9 +1752,88 @@ public abstract class NodeImpl
return false;
}
-
return true;
}
+
+ /**
+ * Tests whether two nodes are equal.
+ *
+ * This method implementation is added, to support use
+ * cases like use of XPath 3.1 function fn:deep-equal.
+ *
+ * <br>This method tests for equality of nodes, not sameness (i.e.,
+ * whether the two nodes are references to the same object) which can be
+ * tested with <code>Node.isSameNode</code>. All nodes that are the same
+ * will also be equal, though the reverse may not be true.
+ * <br>Two nodes are equal if and only if the following conditions are
+ * satisfied: The two nodes are of the same type. The following string
+ * attributes are equal: <code>localName</code>, <code>namespaceURI</code>,
+ * <code>nodeValue</code>, <code>baseURI</code>. This is: they are both
+ * <code>null</code>, or they have the same length and are character
+ * for character identical.
+ * The <code>attributes</code> <code>NamedNodeMaps</code> are equal.
+ * This is: they are both <code>null</code>, or they have the same
+ * length and for each node that exists in one map there is a node that
+ * exists in the other map and is equal, although not necessarily at the
+ * same index. The <code>childNodes</code> <code>NodeLists</code> are
+ * equal. This is: they are both <code>null</code>, or they have the
+ * same length and contain equal nodes at the same index. This is true
+ * for <code>Attr</code> nodes as for any other type of node. Note that
+ * normalization can affect equality; to avoid this, nodes should be
+ * normalized before being compared.
+ * <br>For two <code>DocumentType</code> nodes to be equal, the following
+ * conditions must also be satisfied: The following string attributes
+ * are equal: <code>publicId</code>, <code>systemId</code>,
+ * <code>internalSubset</code>. The <code>entities</code>
+ * <code>NamedNodeMaps</code> are equal. The <code>notations</code>
+ * <code>NamedNodeMaps</code> are equal.
+ * <br>On the other hand, the following do not affect equality: the
+ * <code>ownerDocument</code> attribute, the <code>specified</code>
+ * attribute for <code>Attr</code> nodes, the
+ * <code>isWhitespaceInElementContent</code> attribute for
+ * <code>Text</code> nodes, as well as any user data or event listeners
+ * registered on the nodes.
+ * @param arg The node to compare equality with.
+ * @return If the nodes, and possibly subtrees are equal,
+ * <code>true</code> otherwise <code>false</code>.
+ */
+ public boolean isEqualNodeWithQName(Node arg) {
+ if (arg == this) {
+ return true;
+ }
+ if (arg.getNodeType() != getNodeType()) {
+ return false;
+ }
+
+ if (getLocalName() == null) {
+ if (arg.getLocalName() != null) {
+ return false;
+ }
+ }
+ else if (!getLocalName().equals(arg.getLocalName())) {
+ return false;
+ }
+
+ if (getNamespaceURI() == null) {
+ if (arg.getNamespaceURI() != null) {
+ return false;
+ }
+ }
+ else if (!getNamespaceURI().equals(arg.getNamespaceURI())) {
+ return false;
+ }
+
+ if (getNodeValue() == null) {
+ if (arg.getNodeValue() != null) {
+ return false;
+ }
+ }
+ else if (!getNodeValue().equals(arg.getNodeValue())) {
+ return false;
+ }
+
+ return true;
+ }
/**
* @since DOM Level 3
Modified: xerces/java/trunk/src/org/apache/xerces/dom/ParentNode.java
URL:
http://svn.apache.org/viewvc/xerces/java/trunk/src/org/apache/xerces/dom/ParentNode.java?rev=1915327&r1=1915326&r2=1915327&view=diff
==============================================================================
--- xerces/java/trunk/src/org/apache/xerces/dom/ParentNode.java (original)
+++ xerces/java/trunk/src/org/apache/xerces/dom/ParentNode.java Fri Jan 19
14:19:44 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: [email protected]
For additional commands, e-mail: [email protected]