~ubuntu-branches/ubuntu/trusty/netbeans/trusty

« back to all changes in this revision

Viewing changes to xml/xdm/src/org/netbeans/modules/xml/xdm/diff/XDMUtil.java

  • Committer: Bazaar Package Importer
  • Author(s): Marek Slama
  • Date: 2008-01-29 14:11:22 UTC
  • Revision ID: james.westby@ubuntu.com-20080129141122-fnzjbo11ntghxfu7
Tags: upstream-6.0.1
ImportĀ upstreamĀ versionĀ 6.0.1

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*
 
2
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
 
3
 *
 
4
 * Copyright 1997-2007 Sun Microsystems, Inc. All rights reserved.
 
5
 *
 
6
 * The contents of this file are subject to the terms of either the GNU
 
7
 * General Public License Version 2 only ("GPL") or the Common
 
8
 * Development and Distribution License("CDDL") (collectively, the
 
9
 * "License"). You may not use this file except in compliance with the
 
10
 * License. You can obtain a copy of the License at
 
11
 * http://www.netbeans.org/cddl-gplv2.html
 
12
 * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the
 
13
 * specific language governing permissions and limitations under the
 
14
 * License.  When distributing the software, include this License Header
 
15
 * Notice in each file and include the License file at
 
16
 * nbbuild/licenses/CDDL-GPL-2-CP.  Sun designates this
 
17
 * particular file as subject to the "Classpath" exception as provided
 
18
 * by Sun in the GPL Version 2 section of the License file that
 
19
 * accompanied this code. If applicable, add the following below the
 
20
 * License Header, with the fields enclosed by brackets [] replaced by
 
21
 * your own identifying information:
 
22
 * "Portions Copyrighted [year] [name of copyright owner]"
 
23
 *
 
24
 * Contributor(s):
 
25
 *
 
26
 * The Original Software is NetBeans. The Initial Developer of the Original
 
27
 * Software is Sun Microsystems, Inc. Portions Copyright 1997-2006 Sun
 
28
 * Microsystems, Inc. All Rights Reserved.
 
29
 *
 
30
 * If you wish your version of this file to be governed by only the CDDL
 
31
 * or only the GPL Version 2, indicate your decision by adding
 
32
 * "[Contributor] elects to include this software in this distribution
 
33
 * under the [CDDL or GPL Version 2] license." If you do not indicate a
 
34
 * single choice of license, a recipient has the option to distribute
 
35
 * your version of this file under either the CDDL, the GPL Version 2 or
 
36
 * to extend the choice of license to its licensees as provided above.
 
37
 * However, if you add GPL Version 2 code and therefore, elected the GPL
 
38
 * Version 2 license, then the option applies only if the new code is
 
39
 * made subject to such option by the copyright holder.
 
40
 */
 
41
 
 
42
package org.netbeans.modules.xml.xdm.diff;
 
43
 
 
44
import java.io.IOException;
 
45
import java.io.UnsupportedEncodingException;
 
46
import java.util.ArrayList;
 
47
import java.util.HashMap;
 
48
import java.util.List;
 
49
import java.util.Map;
 
50
import javax.swing.text.BadLocationException;
 
51
import org.netbeans.editor.BaseDocument;
 
52
import org.netbeans.modules.xml.text.syntax.XMLKit;
 
53
import org.netbeans.modules.xml.xam.ModelSource;
 
54
import org.netbeans.modules.xml.xam.dom.ElementIdentity;
 
55
import org.netbeans.modules.xml.xdm.XDMModel;
 
56
import org.netbeans.modules.xml.xdm.nodes.Attribute;
 
57
import org.netbeans.modules.xml.xdm.nodes.Element;
 
58
import org.netbeans.modules.xml.xdm.nodes.Node;
 
59
import org.netbeans.modules.xml.xdm.nodes.NodeImpl;
 
60
import org.netbeans.modules.xml.xdm.nodes.Text;
 
61
import org.netbeans.modules.xml.xdm.diff.Change.AttributeChange;
 
62
import org.netbeans.modules.xml.xdm.visitor.PositionFinderVisitor;
 
63
import org.openide.util.Lookup;
 
64
import org.openide.util.lookup.Lookups;
 
65
import javax.swing.text.Document;
 
66
import org.netbeans.modules.xml.xdm.nodes.Token;
 
67
import org.w3c.dom.NamedNodeMap;
 
68
import org.w3c.dom.NodeList;
 
69
 
 
70
/**
 
71
 *
 
72
 * @author Ayub Khan
 
73
 */
 
74
public class XDMUtil {
 
75
    
 
76
    public enum ComparisonCriteria {
 
77
        EQUAL,
 
78
        IDENTICAL;
 
79
    }
 
80
    
 
81
    /**
 
82
     * Constructor for XDMUtil
 
83
     */
 
84
    public XDMUtil() {
 
85
    }
 
86
 
 
87
    /*
 
88
     * returns a pretty print version of xml doc, using given indentation
 
89
     */
 
90
    public String prettyPrintXML(String doc, String indentation) 
 
91
    throws UnsupportedEncodingException, IOException, BadLocationException {
 
92
        Document sd1 = new BaseDocument(XMLKit.class, false);
 
93
        XDMModel m1 = createXDMModel(sd1, doc);
 
94
        Node root1 = m1.getDocument();
 
95
        
 
96
        Document sd2 = new BaseDocument(XMLKit.class, false);
 
97
        XDMModel m2 = createXDMModel(sd2);
 
98
        m2.setPretty(true);
 
99
        m2.setIndentation(indentation);
 
100
        m2.sync();
 
101
        Node root2 = m2.getDocument();
 
102
        
 
103
        root2 = doPrettyPrint(m2, root2, root1);
 
104
        m2.flush();
 
105
        
 
106
        String prettyXMLStr = sd2.getText(0, sd2.getLength());
 
107
        
 
108
        int firstChildPos1 = -1;
 
109
        Node firstChild1 = (Node) root1.getChildNodes().item(0);
 
110
        if(firstChild1 != null)
 
111
            firstChildPos1 = new PositionFinderVisitor().findPosition(
 
112
                    m1.getDocument(), firstChild1);        
 
113
        
 
114
        int firstChildPos2 = -1;
 
115
        Node firstChild2 = (Node) root2.getChildNodes().item(0);
 
116
        if(firstChild2 != null)
 
117
            firstChildPos2 = new PositionFinderVisitor().findPosition(
 
118
                    m2.getDocument(), firstChild2);  
 
119
        
 
120
        return (firstChildPos1==-1?doc:(sd1.getText(0, firstChildPos1) + 
 
121
                    sd2.getText(firstChildPos2, sd2.getLength() - firstChildPos2)));      
 
122
    }
 
123
    
 
124
    /*
 
125
     * compares 2 xml document contents using a criteria
 
126
     * 
 
127
     * @param firstDoc
 
128
     * @param secondDoc
 
129
     * @param type
 
130
     *   ComparisonCriteria.EQUAL - means Two documents are considered to be
 
131
     *      equal if they contain the same elements and attributes regardless
 
132
     *      of order.
 
133
     *   ComparisonCriteria.IDENTICAL -  means Two documents are considered to
 
134
     *      be "identical" if they contain the same elements and attributes in
 
135
     *      the same order.
 
136
     * filters -
 
137
     *      Whitespace diffs
 
138
     *      Namespace attribute diffs
 
139
     *      Namespace attribute prefix diffs
 
140
     *      Attribute whitespace diffs
 
141
     *
 
142
     * Use the next API (4 argument compareXML api) if you do not want to filter
 
143
     * all of the above 4 types of diffs
 
144
     */  
 
145
    public List<Difference> compareXML(String xml1, String xml2,
 
146
            XDMUtil.ComparisonCriteria criteria)
 
147
            throws Exception {
 
148
        return compareXML(xml1, xml2, criteria, true);
 
149
    }
 
150
    
 
151
    /*
 
152
     * compares 2 xml document contents using a criteria
 
153
     * 
 
154
     * @param firstDoc
 
155
     * @param secondDoc
 
156
     * @param type
 
157
     *   ComparisonCriteria.EQUAL - means Two documents are considered to be
 
158
     *      equal if they contain the same elements and attributes regardless
 
159
     *      of order.
 
160
     *   ComparisonCriteria.IDENTICAL -  means Two documents are considered to
 
161
     *      be "identical" if they contain the same elements and attributes in
 
162
     *      the same order.
 
163
     * @param ignoreWhiteSpace - filters whitespace diffs
 
164
     */    
 
165
    public List<Difference> compareXML(String firstDoc,  
 
166
            String secondDoc, ComparisonCriteria type, boolean filterWhiteSpace) 
 
167
    throws BadLocationException, IOException {
 
168
        Document sd1 = new BaseDocument(XMLKit.class, false);
 
169
        XDMModel m1 = createXDMModel(sd1);
 
170
        sd1.remove(0, XML_PROLOG.length());
 
171
        sd1.insertString(0, firstDoc, null);
 
172
        m1.sync();
 
173
        fDoc = m1.getDocument();        
 
174
        
 
175
        Document sd2 = new BaseDocument(XMLKit.class, false);
 
176
        sd2.getText(0, sd2.getLength());
 
177
        XDMModel m2 = createXDMModel(sd2);        
 
178
        sd2.remove(0, XML_PROLOG.length());
 
179
        sd2.insertString(0, secondDoc, null);
 
180
        m2.setPretty(true);
 
181
        m2.sync();
 
182
        sDoc = m2.getDocument();
 
183
        
 
184
        XDUDiffFinder dif = new XDUDiffFinder(createElementIdentity());
 
185
        List<Difference> diffs = dif.findDiff(m1.getDocument(), m2.getDocument());
 
186
        if(filterWhiteSpace)
 
187
            diffs = XDUDiffFinder.filterWhitespace(diffs);//filter whitespace diffs
 
188
        if(type == ComparisonCriteria.EQUAL) {//remove order change diffs
 
189
            List<Difference> filteredDiffs = new ArrayList<Difference>();
 
190
            for(Difference d:diffs) {
 
191
                if(d instanceof Change) {
 
192
                    Change c = (Change)d;
 
193
                    if(c.isPositionChanged())//node (element/text) pos change
 
194
                        if(!c.isTokenChanged() && !c.isAttributeChanged())
 
195
                            continue;
 
196
                    if(c.isAttributeChanged() && !c.isTokenChanged()) {//attr change only
 
197
                        List<Change.AttributeDiff> removeList = 
 
198
                                new ArrayList<Change.AttributeDiff>();
 
199
                        List<Change.AttributeDiff> attrChanges = c.getAttrChanges();
 
200
                        for(int i=0;i<attrChanges.size();i++) {
 
201
                            if(attrChanges.get(i) instanceof Change.AttributeChange) {
 
202
                                Change.AttributeChange ac = 
 
203
                                    (Change.AttributeChange) attrChanges.get(i);
 
204
                                if(ac.isPositionChanged() && !ac.isTokenChanged())//attr pos change only
 
205
                                    removeList.add(ac);
 
206
                            }
 
207
                        }
 
208
                        for(int i=0;i<removeList.size();i++)
 
209
                            c.removeAttrChanges(removeList.get(i));
 
210
                        if(c.getAttrChanges().size() == 0) //filter this diff
 
211
                            continue;
 
212
                    }
 
213
                    filteredDiffs.add(d);
 
214
                } else {
 
215
                    filteredDiffs.add(d);
 
216
                }
 
217
            }
 
218
            return filteredDiffs;
 
219
        }
 
220
        
 
221
        //remove pseudo attr position changes
 
222
        removePseudoAttrPosChanges(diffs);
 
223
        
 
224
        filterSchemaLocationDiffs(diffs);
 
225
        
 
226
        return diffs;
 
227
    }
 
228
 
 
229
    private ElementIdentity createElementIdentity() {
 
230
        //Establish DOM element identities
 
231
        ElementIdentity eID = new XDElementIdentity();
 
232
        //Following values are suitable for Schema and WSDL documents
 
233
        //these default values can be reset by eID.reset() call
 
234
        eID.addIdentifier( "id" );
 
235
        eID.addIdentifier( "name" );
 
236
        eID.addIdentifier( "ref" );
 
237
        return eID;
 
238
    }
 
239
    
 
240
    private XDMModel createXDMModel(Document sd)
 
241
    throws BadLocationException, IOException {
 
242
        return createXDMModel(sd, "");
 
243
    }
 
244
    
 
245
    private XDMModel createXDMModel(Document sd, String content) 
 
246
    throws BadLocationException, IOException {
 
247
        boolean foundXMLProlog = true;
 
248
        if(content.indexOf("<?xml") == -1) //insert xml prolog, otherwise XMLSyntaxParser will fail
 
249
            sd.insertString(0, XML_PROLOG+content, null);
 
250
        else
 
251
            sd.insertString(0, content, null);
 
252
        Lookup lookup = Lookups.singleton(sd);
 
253
        ModelSource ms = new ModelSource(lookup, true);
 
254
        XDMModel model = new XDMModel(ms);
 
255
        model.sync();
 
256
        return model;
 
257
    }
 
258
    
 
259
    
 
260
    private Node doPrettyPrint(XDMModel m2, Node n2, Node n1) {
 
261
        Node newNode = null;        
 
262
        NodeList childs1 = n1.getChildNodes();
 
263
        int count = 0;
 
264
        for(int i=0;i<childs1.getLength();i++) {
 
265
            n1 = (NodeImpl) childs1.item(i);
 
266
            newNode = ((NodeImpl)n1).cloneNode(true, false);           
 
267
            List<Node> ancestors = m2.add(n2, newNode, count++);
 
268
            n2 = ancestors.get(0);
 
269
        }
 
270
        List<Node> ancestors = new ArrayList<Node>();
 
271
        fixPrettyText(m2, n2, ancestors, "");
 
272
        n2 = ancestors.get(0);
 
273
        return n2;
 
274
    }    
 
275
    
 
276
    private void fixPrettyText(XDMModel m, final Node n, List<Node> ancestors, String indent) {
 
277
        Node parent = n;
 
278
        int index = m.getIndentation().length();
 
279
        NodeList childs = parent.getChildNodes();
 
280
        List<Node> visitList = new ArrayList<Node>();
 
281
        for(int i=0;i<childs.getLength();i++) {
 
282
            Node child = (Node) childs.item(i);
 
283
            if(checkPrettyText(child)) {
 
284
                Text txt = (Text) ((NodeImpl)child).cloneNode(true);
 
285
                if(i < childs.getLength()-1 || ancestors.size() == 0)
 
286
                    txt.setText("\n"+indent);
 
287
                else {
 
288
                    String lastTextIndent = "\n";
 
289
                    if(m.getIndentation().length() < indent.length() )
 
290
                        lastTextIndent += indent.substring(m.getIndentation().length());
 
291
                    txt.setText(lastTextIndent);
 
292
                }
 
293
                List<Node> ancestors2 = m.modify(child, txt);
 
294
                parent = ancestors2.get(0);
 
295
            }
 
296
            else if(childs.item(i) instanceof Element)
 
297
                visitList.add((Node)childs.item(i));
 
298
        }
 
299
        ancestors.add(parent);
 
300
        for(int i=0;i<visitList.size();i++) {
 
301
            fixPrettyText(m, (Node)visitList.get((i)), ancestors, indent+m.getIndentation());
 
302
        }
 
303
        visitList.clear(); //no need to keep it beyond here
 
304
    }    
 
305
 
 
306
    public static boolean checkPrettyText(Node txt) {
 
307
        if (txt instanceof Text) {
 
308
            if ((((NodeImpl)txt).getTokens().size() == 1) &&
 
309
                    isWhitespaceOnly(((NodeImpl)txt).getTokens().get(0).getValue())) {
 
310
                return true;
 
311
            }
 
312
        }
 
313
        return false;
 
314
    }
 
315
    
 
316
    public static boolean isWhitespaceOnly(String tn) {
 
317
        return XDUDiffFinder.isPossibleWhiteSpace(tn) &&
 
318
                tn.trim().length() == 0;
 
319
    }
 
320
    
 
321
 
 
322
    public static int findPosition(final Node n) {
 
323
        return new PositionFinderVisitor().findPosition(
 
324
                (Node)n.getOwnerDocument(), n);
 
325
    }
 
326
    
 
327
    /*
 
328
     * filters or removes diffs that are attr position changes
 
329
     */
 
330
    public static void removePseudoAttrPosChanges(final List<Difference> diffs) {
 
331
        List<Difference> removeDiffs = new ArrayList<Difference>();
 
332
        for(Difference dif:diffs) {
 
333
            if(dif instanceof Change) {
 
334
                Change c = (Change)dif;
 
335
                //filter attibute position changes only
 
336
                if(c.isAttributeChanged() && !c.isPositionChanged() && !c.isTokenChanged()) {
 
337
                    List<Change.AttributeDiff> attrdiffs = c.getAttrChanges();
 
338
                    int size = attrdiffs.size();
 
339
                    List<Change.AttributeDiff> removeAttrs = new ArrayList<Change.AttributeDiff>();
 
340
                    int delCount = 0;
 
341
                    int addCount = 0;
 
342
                    for(Change.AttributeDiff attrdif:attrdiffs) {
 
343
                        if(attrdif instanceof Change.AttributeDelete)
 
344
                            delCount++;
 
345
                        else if(attrdif instanceof Change.AttributeAdd)
 
346
                            addCount++;
 
347
                        else if(attrdif instanceof Change.AttributeChange) {
 
348
                            Change.AttributeChange attrChange =
 
349
                                    (AttributeChange) attrdif;
 
350
                            if(attrChange.isPositionChanged() && !attrChange.isTokenChanged()) {
 
351
                                if((attrChange.getOldAttributePosition() - delCount + addCount) == 
 
352
                                        attrChange.getNewAttributePosition())
 
353
                                    removeAttrs.add(attrdif);
 
354
                            }
 
355
                        }
 
356
                    }
 
357
                    for(Change.AttributeDiff attrdif:removeAttrs) {
 
358
                        c.removeAttrChanges(attrdif);
 
359
                    }
 
360
                    if(size > 0 && c.getAttrChanges().size() == 0)
 
361
                        removeDiffs.add(dif);
 
362
                }
 
363
            }
 
364
        }
 
365
        for(Difference dif:removeDiffs) {
 
366
            diffs.remove(dif);
 
367
        }
 
368
    }
 
369
    
 
370
    /*
 
371
     * filters or removes diffs that are attr position changes
 
372
     */
 
373
    public static void filterAttributeOrderChange(final List<Difference> diffs) {
 
374
        List<Difference> removeDiffs = new ArrayList<Difference>();
 
375
        for(Difference dif:diffs) {
 
376
            if(dif instanceof Change) {
 
377
                Change c = (Change)dif;
 
378
                //filter attibute position changes only
 
379
                if(c.isAttributeChanged() && !c.isPositionChanged() && !c.isTokenChanged()) {
 
380
                    List<Change.AttributeDiff> attrdiffs = c.getAttrChanges();
 
381
                    int size = attrdiffs.size();
 
382
                    List<Change.AttributeDiff> removeAttrs = new ArrayList<Change.AttributeDiff>();
 
383
                    for(Change.AttributeDiff attrdif:attrdiffs) {
 
384
                        if(attrdif instanceof Change.AttributeChange) {
 
385
                            Change.AttributeChange attrChange =
 
386
                                    (AttributeChange) attrdif;
 
387
                            if(attrChange.isPositionChanged() && !attrChange.isTokenChanged())
 
388
                                removeAttrs.add(attrdif);
 
389
                        }
 
390
                    }
 
391
                    for(Change.AttributeDiff attrdif:removeAttrs) {
 
392
                        c.removeAttrChanges(attrdif);
 
393
                    }
 
394
                    if(size > 0 && c.getAttrChanges().size() == 0)
 
395
                        removeDiffs.add(dif);
 
396
                }
 
397
            }
 
398
        }
 
399
        for(Difference dif:removeDiffs) {
 
400
            diffs.remove(dif);
 
401
        }
 
402
    }
 
403
        
 
404
    /*
 
405
     * filters or removes diffs that are schemalocation attr "xsi:schemaLocation='some url'"
 
406
     */
 
407
    public static void filterSchemaLocationDiffs(final List<Difference> diffs) {
 
408
        List<Difference> removeDiffs = new ArrayList<Difference>();
 
409
        for(Difference dif:diffs) {
 
410
            if(dif instanceof Change) {
 
411
                Change c = (Change)dif;
 
412
                //filter namespace attibute changes only
 
413
                if(c.isAttributeChanged() && !c.isPositionChanged() &&
 
414
                        !c.isTokenChanged() && removeSchemaLocationAttrDiffs(c)) {
 
415
                    removeDiffs.add(dif);
 
416
                }
 
417
            }
 
418
        }
 
419
        for(Difference dif:removeDiffs) {
 
420
            diffs.remove(dif);
 
421
        }
 
422
    }
 
423
    
 
424
    /*
 
425
     * removes attr diffs that are ns attr "prefix:schemaLocation='some url'"
 
426
     */
 
427
    public static boolean removeSchemaLocationAttrDiffs(Change c) {
 
428
        List<Change.AttributeDiff> attrdiffs = c.getAttrChanges();
 
429
        int size = attrdiffs.size();
 
430
        List<Change.AttributeDiff> removeAttrs = new ArrayList<Change.AttributeDiff>();
 
431
        for(Change.AttributeDiff attrdif:attrdiffs) {
 
432
            Attribute oldAttr = attrdif.getOldAttribute();
 
433
            Attribute newAttr = attrdif.getNewAttribute();
 
434
            if(oldAttr != null && oldAttr.getName().endsWith(SCHEMA_LOCATION))
 
435
                removeAttrs.add(attrdif);
 
436
            else if(newAttr != null && newAttr.getName().endsWith(SCHEMA_LOCATION))
 
437
                removeAttrs.add(attrdif);
 
438
        }
 
439
        for(Change.AttributeDiff attrdif:removeAttrs) {
 
440
            c.removeAttrChanges(attrdif);
 
441
        }
 
442
        if(size > 0 && attrdiffs.size() == 0)
 
443
            return true;
 
444
        return false;
 
445
    }
 
446
    
 
447
    public class XDElementIdentity extends DefaultElementIdentity {
 
448
 
 
449
        /**
 
450
         * Creates a new instance of DefaultElementIdentity
 
451
         */
 
452
        public XDElementIdentity() {
 
453
            super();
 
454
        }
 
455
 
 
456
        protected boolean compareElement(org.w3c.dom.Element n1, org.w3c.dom.Element n2, org.w3c.dom.Node parent1, org.w3c.dom.Document doc1, org.w3c.dom.Document doc2) {
 
457
            String qName1 = n1.getLocalName();
 
458
            String qName2 = n2.getLocalName();
 
459
            String ns1 = ((Node)n1).getNamespaceURI((org.netbeans.modules.xml.xdm.nodes.Document) doc1);
 
460
            String ns2 = ((Node)n2).getNamespaceURI((org.netbeans.modules.xml.xdm.nodes.Document) doc2);
 
461
 
 
462
            if ( qName1.intern() !=  qName2.intern() )
 
463
                return false;
 
464
            if(!((ns1 == null || ns1.equals("")) && (ns2 == null || ns2.equals("")))) {//can determine ns
 
465
                if ( !(ns1 == null && ns2 == null) &&
 
466
                        !(ns1 != null && ns2 != null && ns1.intern() == ns2.intern() ) )
 
467
                    return false;
 
468
            }
 
469
 
 
470
            if(parent1 == doc1) return true; //if root no need to compare other identifiers
 
471
 
 
472
            return compareAttr( n1, n2);
 
473
        }
 
474
    }
 
475
    
 
476
    public class XDUDiffFinder extends DiffFinder {
 
477
 
 
478
        public XDUDiffFinder(ElementIdentity eID) {
 
479
            super(eID);
 
480
        }
 
481
 
 
482
        public List<Change.Type> checkChange(final Node p1, final Node p2) {
 
483
            List<Change.Type> changes = new ArrayList<Change.Type>();
 
484
            if (p1 instanceof Element && p2 instanceof Element) {
 
485
                if ( ! checkAttributesEqual((Element)p1, (Element)p2)) {
 
486
                    changes.add(Change.Type.ATTRIBUTE);
 
487
                }
 
488
            }
 
489
            return changes;
 
490
        }
 
491
 
 
492
        protected boolean checkAttributesEqual(final Element p1, final Element p2) {
 
493
            if (p1 == null || p2 == null) return false;
 
494
            NamedNodeMap nm1 = p1.getAttributes();
 
495
            NamedNodeMap nm2 = p2.getAttributes();
 
496
            //if( nm1.getLength() != nm2.getLength() ) return false;
 
497
 
 
498
            for ( int i = 0; i < nm1.getLength(); i++ ) {
 
499
                Node attr1 = (Node) nm1.item(i);
 
500
                if(attr1.getNodeName().startsWith("xmlns"))
 
501
                    continue;
 
502
                Node attr2 = (Node) nm2.getNamedItem(attr1.getNodeName());
 
503
                if ( attr2 == null ) return false;
 
504
                if(nm2.item(i) != attr2) return false;
 
505
                if(!attr1.getNodeValue().equals(attr2.getNodeValue()))
 
506
                    return false;
 
507
            }
 
508
            return true;
 
509
        } 
 
510
 
 
511
        protected boolean compareTextByValue(Text n1, Text n2) {
 
512
            return n1.getNodeValue().equals(n2.getNodeValue());
 
513
        }    
 
514
    }
 
515
    
 
516
    static org.netbeans.modules.xml.xdm.nodes.Document fDoc;
 
517
    static org.netbeans.modules.xml.xdm.nodes.Document sDoc;
 
518
    
 
519
    public final static String NS_PREFIX = "xmlns";
 
520
    public final static String SCHEMA_LOCATION = "schemaLocation";    
 
521
    public final static String XML_PROLOG = "<?xml version=\"1.0\"?>\n";
 
522
}