Revision 8719

View differences:

trunk/applications/appCatalogYNomenclatorClient/src/es/gva/cit/catalogClient/metadataXML/XMLNode.java
1 1

  
2 2
/* gvSIG. Sistema de Informaci?n Geogr?fica de la Generalitat Valenciana
3
*
4
* Copyright (C) 2004 IVER T.I. and Generalitat Valenciana.
5
*
6
* This program is free software; you can redistribute it and/or
7
* modify it under the terms of the GNU General Public License
8
* as published by the Free Software Foundation; either version 2
9
* of the License, or (at your option) any later version.
10
*
11
* This program is distributed in the hope that it will be useful,
12
* but WITHOUT ANY WARRANTY; without even the implied warranty of
13
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14
* GNU General Public License for more details.
15
*
16
* You should have received a copy of the GNU General Public License
17
* along with this program; if not, write to the Free Software
18
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307,USA.
19
*
20
* For more information, contact:
21
*
22
*  Generalitat Valenciana
23
*   Conselleria d'Infraestructures i Transport
24
*   Av. Blasco Ib??ez, 50
25
*   46010 VALENCIA
26
*   SPAIN
27
*
28
*      +34 963862235
29
*   gvsig@gva.es
30
*      www.gvsig.gva.es
31
*
32
*    or
33
*
34
*   IVER T.I. S.A
35
*   Salamanca 50
36
*   46005 Valencia
37
*   Spain
38
*
39
*   +34 963163400
40
*   dac@iver.es
41
*/
3
 *
4
 * Copyright (C) 2004 IVER T.I. and Generalitat Valenciana.
5
 *
6
 * This program is free software; you can redistribute it and/or
7
 * modify it under the terms of the GNU General Public License
8
 * as published by the Free Software Foundation; either version 2
9
 * of the License, or (at your option) any later version.
10
 *
11
 * This program is distributed in the hope that it will be useful,
12
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14
 * GNU General Public License for more details.
15
 *
16
 * You should have received a copy of the GNU General Public License
17
 * along with this program; if not, write to the Free Software
18
 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307,USA.
19
 *
20
 * For more information, contact:
21
 *
22
 *  Generalitat Valenciana
23
 *   Conselleria d'Infraestructures i Transport
24
 *   Av. Blasco Ib??ez, 50
25
 *   46010 VALENCIA
26
 *   SPAIN
27
 *
28
 *      +34 963862235
29
 *   gvsig@gva.es
30
 *      www.gvsig.gva.es
31
 *
32
 *    or
33
 *
34
 *   IVER T.I. S.A
35
 *   Salamanca 50
36
 *   46005 Valencia
37
 *   Spain
38
 *
39
 *   +34 963163400
40
 *   dac@iver.es
41
 */
42 42
package es.gva.cit.catalogClient.metadataXML;
43 43
import java.io.File;
44 44
import java.io.FileWriter;
......
64 64
 */
65 65
public class XMLNode {
66 66
	public static final String ISNOTXML = "NOTXML";
67

  
68
/**
69
 * 
70
 * 
71
 */
72
    private Vector subNodes = new Vector();
73

  
74
/**
75
 * 
76
 * 
77
 */
78
    private String cdata = null;
79
// atributos
80

  
81
/**
82
 * 
83
 * 
84
 */
85
    private Hashtable attr = new Hashtable();
86

  
87
/**
88
 * 
89
 * 
90
 */
91
    private String nodeName;
92

  
93
/**
94
 * 
95
 * 
96
 */
97
    private String text = null;
98
// los nombres de los atributos
99

  
100
/**
101
 * 
102
 * 
103
 */
104
    private Vector attrKeys = new Vector();
105
// cabecera XML
106

  
107
/**
108
 * 
109
 * 
110
 */
111
    private String header = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n";
112

  
113
/**
114
 * Constructor, lee de un fichero
115
 * 
116
 * 
117
 * @param file 
118
 * @author jaume - jaume.dominguez@iver.es
119
 * Modified by Jorge Piera Llodra - piera_jor@gva.es
120
 */
121
    public  XMLNode(File file) throws Exception {        
122
      this(factory.newDocumentBuilder().parse(file));
123
    } 
124

  
125
/**
126
 * Constructor. Usando url.openStream() se puede usar
127
 * para leer info descargada de internet.
128
 * 
129
 * 
130
 * @param inputstream 
131
 * @throws Exception
132
 */
133
    public  XMLNode(InputStream inputstream) throws Exception {        
134
       this(factory.newDocumentBuilder().parse(inputstream));
135
    } 
136

  
137
/**
138
 * Contructor, constructor desde un documento DOM
139
 * 
140
 * 
141
 * @param dom 
142
 * @author jaume - jaume.dominguez@iver.es
143
 */
144
    public  XMLNode(Document dom) throws Exception {        
145
      this((Element)dom.getFirstChild());
146
    } 
147

  
148
/**
149
 * Contructor, crea un nodo con su nombre
150
 * 
151
 * 
152
 * @param name 
153
 */
154
    public  XMLNode(String name) throws Exception {        
155
      nodeName = name;
156
    } 
157

  
158
/**
159
 * Contructor, crea un nodo con su nombre y el texto
160
 * 
161
 * 
162
 * @param name 
163
 * @param text 
164
 */
165
    public  XMLNode(String name, String text) throws Exception {        
166
      nodeName = name;
167
      this.text = text;
168
    } 
169

  
170
/**
171
 * Contructor, desde un elemento DOM
172
 * 
173
 * 
174
 * @param dom 
175
 */
176
    public  XMLNode(Element dom) throws Exception {        
177
      nodeName = dom.getNodeName();
178
      NamedNodeMap map = dom.getAttributes();
179
      for (int i = 0; i < map.getLength(); i++) {
180
         Node att = map.item(i);
181
         addAtrribute(att.getNodeName(), att.getNodeValue());
182
         
183
      }
184
      NodeList nodeList = dom.getChildNodes();
185
      for (int i = 0; i < nodeList.getLength(); i++) {
186
         Node sub = nodeList.item(i);
187
         if (sub.getNodeType() == Node.ELEMENT_NODE) {
188
            addSubNode(new XMLNode((Element)sub));
189
         }else if (sub.getNodeType() == Node.CDATA_SECTION_NODE){
190
             String sCdata = sub.getNodeValue().trim();   
191
             if (sCdata.length() > 0) {
192
                 cdata = sCdata; 
193
             }
194
         }else if (sub.getNodeType() == Node.TEXT_NODE) {
195
            String s = sub.getNodeValue().trim();
196
            if (s.length() > 0) {
197
               if (text != null) {
198
                  throw new Exception("XMLNode '" + nodeName + "' has 2 Textblocks");
199
               }
200
               text = s;
201
            }
202
         }
203
      }
204
    } 
205

  
206
/**
207
 * 
208
 * 
209
 * 
210
 * @param s 
211
 */
212
    public void setText(String s) {        
213
      text = s;
214
    } 
215

  
216
/**
217
 * 
218
 * 
219
 * 
220
 * @param s 
221
 */
222
    public void addSubNode(XMLNode s) {        
223
      subNodes.add(s);
224
    } 
225

  
226
/**
227
 * 
228
 * 
229
 * 
230
 * @param name 
231
 * @param value 
232
 */
233
    public void addAtrribute(String name, String value) throws Exception {        
234
      if (attr.containsKey(name)) {
235
         throw new Exception(
236
               "XMLNode '" + nodeName + "' already contains Attribute '" + name + "'");
237
      }
238
      attr.put(name, value);
239
      attrKeys.add(name);
240
    } 
241

  
242
/**
243
 * 
244
 * 
245
 * 
246
 * @return 
247
 */
248
    public int getNumSubNodes() {        
249
      return subNodes.size();
250
    } 
251

  
252
/**
253
 * 
254
 * 
255
 * 
256
 * @return 
257
 */
258
    public String getName() {        
259
      return nodeName;
260
    } 
261

  
262
/**
263
 * 
264
 * 
265
 * 
266
 * @return 
267
 */
268
    public String getText() {        
269
      return text;
270
    } 
271

  
272
/**
273
 * 
274
 * 
275
 * 
276
 * @return 
277
 */
278
    public String getCdata() {        
279
       return cdata;
280
    } 
281

  
282
/**
283
 * 
284
 * 
285
 * 
286
 * @return 
287
 * @param index 
288
 */
289
    public XMLNode getSubNode(int index) {        
290
      return (XMLNode)subNodes.get(index);
291
    } 
292

  
293
/**
294
 * 
295
 * 
296
 * 
297
 * @return 
298
 */
299
    public XMLNode[] getSubnodes() {        
300
       XMLNode[] xmlNodes = new XMLNode[getNumSubNodes()];
301
       for (int i=0 ; i<getNumSubNodes() ; i++){
302
           xmlNodes[i] = getSubNode(i);
303
       }
304
       return xmlNodes;
305
    } 
306

  
307
/**
308
 * 
309
 * 
310
 * 
311
 * @return 
312
 */
313
    public Vector getAttributeNames() {        
314
       return attrKeys;
315
    } 
316

  
317
/**
318
 * 
319
 * 
320
 * 
321
 * @param wr 
322
 */
323
    public void write(Writer wr) throws Exception {        
324
      wwrite("", wr);
325
    } 
326

  
327
/**
328
 * Escribe el c?digo XML de este objeto con su identaci?n
329
 * 
330
 * 
331
 * @param pre 
332
 * @param wr 
333
 */
334
    private void wwrite(String pre, Writer wr) throws Exception {        
335
      wr.write(pre + "<" + nodeName);
336
      for (int i = 0; i < attrKeys.size(); i++) {
337
         String name = (String)attrKeys.get(i);
338
         String val = (String)attr.get(name);
339
         wr.write(" " + name + "='" + val + "'");
340
      }
341
      if (getNumSubNodes() == 0 && text == null) {
342
         wr.write("/>\n");
343
      }
344
      else {
345
         wr.write(">");
346
         if (text != null) {
347
            wr.write(text);
348
         }
349
         if (getNumSubNodes() > 0) {
350
            wr.write("\n");
351
            for (int i = 0; i < subNodes.size(); i++) {
352
               if (getSubNode(i) != null) {
353
                  getSubNode(i).wwrite(pre + "  ", wr);
354
               }
355
            }
356
            wr.write(pre + "</" + nodeName + ">\n");
357
         }
358
         else {
359
            wr.write("</" + nodeName + ">\n");
360
         }
361
      }
362
    } 
363

  
364
/**
365
 * 
366
 * 
367
 * 
368
 * @return 
369
 * @param key 
370
 */
371
    public String getAttribute(String key) {        
372
      return (String)attr.get(key);
373
    } 
374

  
375
/**
376
 * 
377
 * 
378
 * 
379
 * @return 
380
 * @param key 
381
 */
382
    public double getDoubleAttribute(String key) {        
383
      return Double.parseDouble((String)attr.get(key));
384
    } 
385

  
386
/**
387
 * 
388
 * 
389
 * 
390
 * @return 
391
 * @param key 
392
 */
393
    public boolean getBoolAttribute(String key) {        
394
      if (!hasAttribute(key)) {
395
         return false;
396
      }
397
      return new Boolean((String)attr.get(key)).booleanValue();
398
    } 
399

  
400
/**
401
 * 
402
 * 
403
 * 
404
 * @return 
405
 * @param key 
406
 */
407
    public int getIntAttribute(String key) {        
408
      return Integer.parseInt((String)attr.get(key));
409
    } 
410

  
411
/**
412
 * 
413
 * 
414
 * 
415
 * @return 
416
 * @param key 
417
 */
418
    public boolean hasAttribute(String key) {        
419
      return attr.containsKey(key);
420
    } 
421
// escribe al fichero
422

  
423
/**
424
 * 
425
 * 
426
 * 
427
 * @param f 
428
 */
429
    public void write(File f) throws Exception {        
430
      FileWriter fw = new FileWriter(f);
431
      fw.write(header);
432
      write(fw);
433
      fw.flush();
434
      fw.close();
435
    } 
436

  
437
/**
438
 * 
439
 * 
440
 * 
441
 * @return 
442
 */
443
    public String toString() {        
444
      return this.getName();
445
      /*
446
       StringWriter wr = new StringWriter();
447
      try {
448
         write(wr);
449
      }
450
      catch (Exception e) {
451
         System.err.println("Exception in StringWriter " + e);
452
         e.printStackTrace();
453
         System.exit(1);
454
      }
455
      return wr.toString();
456
      */
457
    } 
458
/**
459
 * 
460
 * 
461
 */
462
    static DocumentBuilderFactory factory;
463

  
464
/**
465
 * 
466
 * 
467
 */
468
    static {        
469
      factory = DocumentBuilderFactory.newInstance();
470
      factory.setValidating(false);
471
      factory.setNamespaceAware(false);
472
      factory.setIgnoringComments(true);
473
    }  
474

  
475
/**
476
 * 
477
 * 
478
 * 
479
 * @param header 
480
 */
481
    public void setHeader(String header) {        
482
      this.header = header;
483
    } 
484

  
485
/**
486
 * This method prints all the child nodes. It is used only for
487
 * fixing bugs.
488
 * 
489
 */
490
    public void printSubNodes() {        
491
       for (int i=0 ; i<getNumSubNodes() ; i++){
492
           System.out.println(getSubNode(i).getName() + " = " + getSubNode(i).getText());
493
       }
494
    } 
495
 }
67
	
68
	/**
69
	 * 
70
	 * 
71
	 */
72
	private Vector subNodes = new Vector();
73
	
74
	/**
75
	 * 
76
	 * 
77
	 */
78
	private String cdata = null;
79
//	atributos
80
	
81
	/**
82
	 * 
83
	 * 
84
	 */
85
	private Hashtable attr = new Hashtable();
86
	
87
	/**
88
	 * 
89
	 * 
90
	 */
91
	private String nodeName;
92
	
93
	/**
94
	 * 
95
	 * 
96
	 */
97
	private String text = null;
98
//	los nombres de los atributos
99
	
100
	/**
101
	 * 
102
	 * 
103
	 */
104
	private Vector attrKeys = new Vector();
105
//	cabecera XML
106
	
107
	/**
108
	 * 
109
	 * 
110
	 */
111
	private String header = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n";
112
	
113
	/**
114
	 * Constructor, lee de un fichero
115
	 * 
116
	 * 
117
	 * @param file 
118
	 * @author jaume - jaume.dominguez@iver.es
119
	 * Modified by Jorge Piera Llodra - piera_jor@gva.es
120
	 */
121
	public  XMLNode(File file) throws Exception {        
122
		this(factory.newDocumentBuilder().parse(file));
123
	} 
124
	
125
	/**
126
	 * Constructor. Usando url.openStream() se puede usar
127
	 * para leer info descargada de internet.
128
	 * 
129
	 * 
130
	 * @param inputstream 
131
	 * @throws Exception
132
	 */
133
	public  XMLNode(InputStream inputstream) throws Exception {        
134
		this(factory.newDocumentBuilder().parse(inputstream));
135
	} 
136
	
137
	/**
138
	 * Contructor, constructor desde un documento DOM
139
	 * 
140
	 * 
141
	 * @param dom 
142
	 * @author jaume - jaume.dominguez@iver.es
143
	 */
144
	public  XMLNode(Document dom) throws Exception {        
145
		this((Element)dom.getFirstChild());
146
	} 
147
	
148
	/**
149
	 * Contructor, crea un nodo con su nombre
150
	 * 
151
	 * 
152
	 * @param name 
153
	 */
154
	public  XMLNode(String name) throws Exception {        
155
		nodeName = name;
156
	} 
157
	
158
	/**
159
	 * Contructor, crea un nodo con su nombre y el texto
160
	 * 
161
	 * 
162
	 * @param name 
163
	 * @param text 
164
	 */
165
	public  XMLNode(String name, String text) throws Exception {        
166
		nodeName = name;
167
		this.text = text;
168
	} 
169
	
170
	/**
171
	 * Contructor, desde un elemento DOM
172
	 * 
173
	 * 
174
	 * @param dom 
175
	 */
176
	public  XMLNode(Element dom) throws Exception {        
177
		nodeName = dom.getNodeName();
178
		NamedNodeMap map = dom.getAttributes();
179
		for (int i = 0; i < map.getLength(); i++) {
180
			Node att = map.item(i);
181
			addAtrribute(att.getNodeName(), att.getNodeValue());
182
			
183
		}
184
		NodeList nodeList = dom.getChildNodes();
185
		for (int i = 0; i < nodeList.getLength(); i++) {
186
			Node sub = nodeList.item(i);
187
			if (sub.getNodeType() == Node.ELEMENT_NODE) {
188
				addSubNode(new XMLNode((Element)sub));
189
			}else if (sub.getNodeType() == Node.CDATA_SECTION_NODE){
190
				String sCdata = sub.getNodeValue().trim();   
191
				if (sCdata.length() > 0) {
192
					cdata = sCdata; 
193
				}
194
			}else if (sub.getNodeType() == Node.TEXT_NODE) {
195
				String s = sub.getNodeValue().trim();
196
				if (s.length() > 0) {
197
					if (text != null) {
198
						throw new Exception("XMLNode '" + nodeName + "' has 2 Textblocks");
199
					}
200
					text = s;
201
				}
202
			}
203
		}
204
	} 
205
	
206
	/**
207
	 * 
208
	 * 
209
	 * 
210
	 * @param s 
211
	 */
212
	public void setText(String s) {        
213
		text = s;
214
	} 
215
	
216
	/**
217
	 * 
218
	 * 
219
	 * 
220
	 * @param s 
221
	 */
222
	public void addSubNode(XMLNode s) {        
223
		subNodes.add(s);
224
	} 
225
	
226
	/**
227
	 * 
228
	 * 
229
	 * 
230
	 * @param name 
231
	 * @param value 
232
	 */
233
	public void addAtrribute(String name, String value) throws Exception {        
234
		if (attr.containsKey(name)) {
235
			throw new Exception(
236
					"XMLNode '" + nodeName + "' already contains Attribute '" + name + "'");
237
		}
238
		attr.put(name, value);
239
		attrKeys.add(name);
240
	} 
241
	
242
	/**
243
	 * 
244
	 * 
245
	 * 
246
	 * @return 
247
	 */
248
	public int getNumSubNodes() {        
249
		return subNodes.size();
250
	} 
251
	
252
	/**
253
	 * 
254
	 * 
255
	 * 
256
	 * @return 
257
	 */
258
	public String getName() {        
259
		return nodeName;
260
	} 
261
	
262
	/**
263
	 * 
264
	 * 
265
	 * 
266
	 * @return 
267
	 */
268
	public String getText() {        
269
		return text;
270
	} 
271
	
272
	/**
273
	 * 
274
	 * 
275
	 * 
276
	 * @return 
277
	 */
278
	public String getCdata() {        
279
		return cdata;
280
	} 
281
	
282
	/**
283
	 * 
284
	 * 
285
	 * 
286
	 * @return 
287
	 * @param index 
288
	 */
289
	public XMLNode getSubNode(int index) {        
290
		return (XMLNode)subNodes.get(index);
291
	} 
292
	
293
	/**
294
	 * 
295
	 * 
296
	 * 
297
	 * @return 
298
	 */
299
	public XMLNode[] getSubnodes() {        
300
		XMLNode[] xmlNodes = new XMLNode[getNumSubNodes()];
301
		for (int i=0 ; i<getNumSubNodes() ; i++){
302
			xmlNodes[i] = getSubNode(i);
303
		}
304
		return xmlNodes;
305
	} 
306
	
307
	/**
308
	 * 
309
	 * 
310
	 * 
311
	 * @return 
312
	 */
313
	public Vector getAttributeNames() {        
314
		return attrKeys;
315
	} 
316
	
317
	/**
318
	 * 
319
	 * 
320
	 * 
321
	 * @param wr 
322
	 */
323
	public void write(Writer wr) throws Exception {        
324
		wwrite("", wr);
325
	} 
326
	
327
	/**
328
	 * Escribe el c?digo XML de este objeto con su identaci?n
329
	 * 
330
	 * 
331
	 * @param pre 
332
	 * @param wr 
333
	 */
334
	private void wwrite(String pre, Writer wr) throws Exception {        
335
		wr.write(pre + "<" + nodeName);
336
		for (int i = 0; i < attrKeys.size(); i++) {
337
			String name = (String)attrKeys.get(i);
338
			String val = (String)attr.get(name);
339
			wr.write(" " + name + "='" + val + "'");
340
		}
341
		if (getNumSubNodes() == 0 && text == null) {
342
			wr.write("/>\n");
343
		}
344
		else {
345
			wr.write(">");
346
			if (text != null) {
347
				wr.write(text);
348
			}
349
			if (getNumSubNodes() > 0) {
350
				wr.write("\n");
351
				for (int i = 0; i < subNodes.size(); i++) {
352
					if (getSubNode(i) != null) {
353
						getSubNode(i).wwrite(pre + "  ", wr);
354
					}
355
				}
356
				wr.write(pre + "</" + nodeName + ">\n");
357
			}
358
			else {
359
				wr.write("</" + nodeName + ">\n");
360
			}
361
		}
362
	} 
363
	
364
	/**
365
	 * 
366
	 * 
367
	 * 
368
	 * @return 
369
	 * @param key 
370
	 */
371
	public String getAttribute(String key) {        
372
		return (String)attr.get(key);
373
	} 
374
	
375
	/**
376
	 * 
377
	 * 
378
	 * 
379
	 * @return 
380
	 * @param key 
381
	 */
382
	public double getDoubleAttribute(String key) {        
383
		return Double.parseDouble((String)attr.get(key));
384
	} 
385
	
386
	/**
387
	 * 
388
	 * 
389
	 * 
390
	 * @return 
391
	 * @param key 
392
	 */
393
	public boolean getBoolAttribute(String key) {        
394
		if (!hasAttribute(key)) {
395
			return false;
396
		}
397
		return new Boolean((String)attr.get(key)).booleanValue();
398
	} 
399
	
400
	/**
401
	 * 
402
	 * 
403
	 * 
404
	 * @return 
405
	 * @param key 
406
	 */
407
	public int getIntAttribute(String key) {        
408
		return Integer.parseInt((String)attr.get(key));
409
	} 
410
	
411
	/**
412
	 * 
413
	 * 
414
	 * 
415
	 * @return 
416
	 * @param key 
417
	 */
418
	public boolean hasAttribute(String key) {        
419
		return attr.containsKey(key);
420
	} 
421
//	escribe al fichero
422
	
423
	/**
424
	 * 
425
	 * 
426
	 * 
427
	 * @param f 
428
	 */
429
	public void write(File f) throws Exception {        
430
		FileWriter fw = new FileWriter(f);
431
		fw.write(header);
432
		write(fw);
433
		fw.flush();
434
		fw.close();
435
	} 
436
	
437
	/**
438
	 * 
439
	 * 
440
	 * 
441
	 * @return 
442
	 */
443
	public String toString() {        
444
		return this.getName();
445
		/*
446
		 StringWriter wr = new StringWriter();
447
		 try {
448
		 write(wr);
449
		 }
450
		 catch (Exception e) {
451
		 System.err.println("Exception in StringWriter " + e);
452
		 e.printStackTrace();
453
		 System.exit(1);
454
		 }
455
		 return wr.toString();
456
		 */
457
	} 
458
	/**
459
	 * 
460
	 * 
461
	 */
462
	static DocumentBuilderFactory factory;
463
	
464
	/**
465
	 * 
466
	 * 
467
	 */
468
	static {        
469
		factory = DocumentBuilderFactory.newInstance();
470
		factory.setValidating(false);
471
		factory.setNamespaceAware(false);
472
		factory.setIgnoringComments(true);
473
	}  
474
	
475
	/**
476
	 * 
477
	 * 
478
	 * 
479
	 * @param header 
480
	 */
481
	public void setHeader(String header) {        
482
		this.header = header;
483
	} 
484
	
485
	/**
486
	 * This method prints all the child nodes. It is used only for
487
	 * fixing bugs.
488
	 * 
489
	 */
490
	public void printSubNodes() {        
491
		for (int i=0 ; i<getNumSubNodes() ; i++){
492
			System.out.println(getSubNode(i).getName() + " = " + getSubNode(i).getText());
493
		}
494
	} 
495
	
496
	/**
497
	 * This method prints a node in the standard output. Just for degug
498
	 * @param node
499
	 */
500
	public void printNode() {        
501
		printNode(this);
502
	} 
503
	
504
	private void printNode(XMLNode node){
505
		System.out.print("<" + node.getName());
506
		for (int i = 0; i < node.getAttributeNames().size(); i++) {
507
			String name = (String)node.getAttributeNames().get(i);
508
			String val = (String)node.getAttribute(name);
509
			System.out.print(" " + name + "='" + val + "'");
510
		}
511
		if (node.getNumSubNodes() == 0 && node.getText() == null) {
512
			System.out.print("/>\n");
513
		}
514
		else {
515
			System.out.print(">");
516
			if (node.getText() != null) {
517
				System.out.println(node.getText());
518
			}
519
			if (node.getNumSubNodes() > 0) {
520
				System.out.print("\n");
521
				for (int i = 0; i < node.getSubnodes().length; i++) {
522
					if (node.getSubnodes()[i] != null) {
523
						printNode(node.getSubnodes()[i]);
524
					}
525
				}
526
				System.out.print("</" + node.getName() + ">\n");
527
			}
528
			else {
529
				System.out.print("</" + node.getName() + ">\n");
530
			}
531
		}
532
	}
533
}

Also available in: Unified diff