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