1 package net.sf.saxon.functions; 2 import net.sf.saxon.Configuration; 3 import net.sf.saxon.expr.Expression; 4 import net.sf.saxon.expr.StaticContext; 5 import net.sf.saxon.expr.XPathContext; 6 import net.sf.saxon.om.*; 7 import net.sf.saxon.pattern.NameTest; 8 import net.sf.saxon.sort.AtomicComparer; 9 import net.sf.saxon.trans.XPathException; 10 import net.sf.saxon.type.Type; 11 import net.sf.saxon.value.BooleanValue; 12 13 18 19 public class DeepEqual extends CollatingFunction { 20 21 private transient Configuration config = null; 22 23 26 27 public Expression preEvaluate(StaticContext env) throws XPathException { 28 config = env.getConfiguration(); 29 return super.preEvaluate(env); 30 } 31 32 35 36 public Item evaluateItem(XPathContext context) throws XPathException { 37 AtomicComparer collator = getAtomicComparer(2, context); 38 39 SequenceIterator op1 = argument[0].iterate(context); 40 SequenceIterator op2 = argument[1].iterate(context); 41 42 Configuration config = 43 (this.config!=null ? this.config : context.getController().getConfiguration()); 44 return BooleanValue.get(deepEquals(op1, op2, collator, config)); 45 } 46 47 55 56 public static boolean deepEquals(SequenceIterator op1, SequenceIterator op2, 57 AtomicComparer collator, Configuration config) { 58 boolean result = true; 59 try { 60 while (true) { 61 Item item1 = op1.next(); 62 Item item2 = op2.next(); 63 64 if (item1 == null && item2 == null) { 65 break; 66 } 67 68 if (item1 == null || item2 == null) { 69 result = false; 70 break; 71 } 72 73 if (item1 instanceof NodeInfo) { 74 if (item2 instanceof NodeInfo) { 75 if (!deepEquals((NodeInfo)item1, (NodeInfo)item2, collator, config)) { 76 result = false; 77 break; 78 } 79 } else { 80 result = false; 81 break; 82 } 83 } else { 84 if (item2 instanceof NodeInfo) { 85 result = false; 86 break; 87 } else { 88 if (!collator.comparesEqual(item1, item2)) { 89 result = false; 90 break; 91 } 92 } 93 } 94 } 96 } catch (ClassCastException err) { 97 result = false; 100 } catch (XPathException err) { 101 result = false; 103 } 104 105 return result; 106 } 107 108 111 112 private static boolean deepEquals(NodeInfo n1, NodeInfo n2, 113 AtomicComparer collator, Configuration config) 114 throws XPathException { 115 if (n1.isSameNodeInfo(n2)) return true; 117 118 if (n1.getNodeKind() != n2.getNodeKind()) return false; 119 switch (n1.getNodeKind()) { 120 case Type.ELEMENT: 121 if (n1.getFingerprint() != n2.getFingerprint()) { 122 return false; 123 } 124 AxisIterator a1 = n1.iterateAxis(Axis.ATTRIBUTE); 125 AxisIterator a2 = n2.iterateAxis(Axis.ATTRIBUTE); 126 if (Aggregate.count(a1.getAnother()) != Aggregate.count(a2)) { 127 return false; 128 } 129 while (true) { 130 NodeInfo att1 = (NodeInfo)a1.next(); 131 if (att1 == null) break; 132 133 AxisIterator a2iter = n2.iterateAxis(Axis.ATTRIBUTE, 134 new NameTest(Type.ATTRIBUTE, att1.getFingerprint(), config.getNamePool())); 135 NodeInfo att2 = (NodeInfo)a2iter.next(); 136 137 if (att2==null) { 138 return false; 139 } 140 if (!deepEquals(att1, att2, collator, config)) { 141 return false; 142 } 143 } 144 case Type.DOCUMENT: 146 AxisIterator c1 = n1.iterateAxis(Axis.CHILD); 147 AxisIterator c2 = n2.iterateAxis(Axis.CHILD); 148 while (true) { 149 NodeInfo d1 = (NodeInfo)c1.next(); 150 while (d1 != null && ( 151 d1.getNodeKind() == Type.COMMENT || 152 d1.getNodeKind() == Type.PROCESSING_INSTRUCTION)) { 153 d1 = (NodeInfo)c1.next(); 154 } 155 NodeInfo d2 = (NodeInfo)c2.next(); 156 while (d2 != null && ( 157 d2.getNodeKind() == Type.COMMENT || 158 d2.getNodeKind() == Type.PROCESSING_INSTRUCTION)) { 159 d2 = (NodeInfo)c2.next(); 160 } 161 if (d1 == null || d2 == null) { 162 return (d1 == d2); 163 } 164 if (!deepEquals(d1, d2, collator, config)) { 165 return false; 166 } 167 } 168 169 170 case Type.ATTRIBUTE: 171 if (n1.getFingerprint() != n2.getFingerprint()) { 172 return false; 173 } 174 return deepEquals(n1.getTypedValue(), n2.getTypedValue(), collator, config); 175 176 case Type.PROCESSING_INSTRUCTION: 177 case Type.NAMESPACE: 178 if (n1.getFingerprint() != n2.getFingerprint()) { 179 return false; 180 } 181 case Type.TEXT: 183 case Type.COMMENT: 184 return (collator.comparesEqual(n1.getStringValue(), n2.getStringValue())); 185 186 default: 187 throw new IllegalArgumentException ("Unknown node type"); 188 } 189 } 190 191 } 192 193 | Popular Tags |