source: gli/trunk/src/org/greenstone/gatherer/util/XMLTools.java@ 16331

Last change on this file since 16331 was 16331, checked in by ak19, 16 years ago

Fixed a bug in showXMLParseFailureLine() and it now informs the debugger when there's a newline or empty space before the start of the xml tags (this won't be clear from the erroneous line that's printed out, since that line will be empty.

  • Property svn:keywords set to Author Date Id Revision
File size: 32.0 KB
Line 
1package org.greenstone.gatherer.util;
2
3
4import java.io.*;
5import java.net.*;
6import java.util.*;
7import org.apache.xerces.parsers.*;
8import org.apache.xml.serialize.*;
9import org.greenstone.gatherer.DebugStream;
10import org.w3c.dom.*;
11import org.xml.sax.*;
12
13import java.io.FileReader;
14import java.io.IOException;
15import java.io.StringReader;
16
17// SAX
18import org.xml.sax.XMLReader;
19import org.xml.sax.SAXException;
20import org.xml.sax.SAXParseException;
21import org.xml.sax.helpers.DefaultHandler;
22import org.xml.sax.InputSource;
23
24// JAXP
25import javax.xml.parsers.FactoryConfigurationError;
26import javax.xml.parsers.ParserConfigurationException;
27import javax.xml.parsers.SAXParser;
28import javax.xml.parsers.SAXParserFactory;
29
30/** This class is a static class containing useful XML functions */
31public class XMLTools {
32 /** extracts the text out of a node */
33 public static Node getNodeTextNode (Element param) {
34 param.normalize ();
35 Node n = param.getFirstChild ();
36 while (n!=null && n.getNodeType () !=Node.TEXT_NODE) {
37 n=n.getNextSibling ();
38 }
39 return n;
40 }
41
42 /** extracts the text out of a node */
43 public static String getNodeText (Element param) {
44 Node text_node = getNodeTextNode (param);
45 if (text_node == null) {
46 return "";
47 }
48 return text_node.getNodeValue ();
49 }
50 public static void setNodeText (Element elem, String text) {
51 Node old_text_node = getNodeTextNode (elem);
52 if (old_text_node != null) {
53 elem.removeChild (old_text_node);
54 }
55 Text t = elem.getOwnerDocument ().createTextNode (text);
56 elem.appendChild (t);
57 }
58 /** returns the (first) child element with the given name */
59 public static Node getChildByTagName (Node n, String name) {
60
61 Node child = n.getFirstChild ();
62 while (child!=null) {
63 if (child.getNodeName ().equals (name)) {
64 return child;
65 }
66 child = child.getNextSibling ();
67 }
68 return null; //not found
69 }
70
71 /** returns the (nth) child element with the given name
72 * index numbers start at 0 */
73 public static Node getChildByTagNameIndexed (Node n, String name, int index) {
74 if (index == -1) {
75 return getChildByTagName (n, name);
76 }
77 int count = 0;
78 Node child = n.getFirstChild ();
79 while (child!=null) {
80 if (child.getNodeName ().equals (name)) {
81 if (count == index) {
82 return child;
83 } else {
84 count++;
85 }
86 }
87 child = child.getNextSibling ();
88 }
89 return null; //not found
90 }
91
92 /** returns the element parent/node_name[@attribute_name='attribute_value']
93 */
94 public static Element getNamedElement (Element parent, String node_name,
95 String attribute_name,
96 String attribute_value) {
97
98 NodeList children = parent.getChildNodes ();
99 for (int i=0; i<children.getLength (); i++) {
100 Node child = children.item (i);
101 //logger.debug("getnamed elem, node nmae="+child.getNodeName());
102 if (child.getNodeName ().equals (node_name)) {
103 if (((Element)child).getAttribute (attribute_name).equals (attribute_value))
104 return (Element)child;
105 }
106 }
107 // not found
108 return null;
109 }
110 /** returns a list of elements parent/node_name[@attribute_name='attribute_value']
111 */
112 public static ArrayList getNamedElementList (Element parent, String node_name,
113 String attribute_name,
114 String attribute_value) {
115 ArrayList elements = new ArrayList ();
116 NodeList children = parent.getChildNodes ();
117 for (int i=0; i<children.getLength (); i++) {
118 //System.out.println("getNamedElementList");
119 Node child = children.item (i);
120 //logger.debug("getnamed elem, node nmae="+child.getNodeName());
121 if (child.getNodeName ().equals (node_name)) {
122 if (((Element)child).getAttribute (attribute_name).equals (attribute_value))
123 elements.add ((Element)child);
124 }
125 }
126 // not found
127 if (elements.size () == 0) {
128 elements = null;
129 }
130 return elements;
131 }
132 public static void copyAllChildren (Element to, Element from) {
133
134 Document to_doc = to.getOwnerDocument ();
135 Node child = from.getFirstChild ();
136 while (child != null) {
137 to.appendChild (to_doc.importNode (child, true));
138 child = child.getNextSibling ();
139 }
140 }
141 /** Duplicates an element */
142 public static Element duplicateElement (Document owner, Element element, boolean with_attributes) {
143 return duplicateElementNS (owner, element, null, with_attributes);
144 }
145
146 /** Duplicates an element */
147 public static Element duplicateElementNS (Document owner,
148 Element element,
149 String namespace_uri,
150 boolean with_attributes) {
151 Element duplicate;
152 if (namespace_uri == null) {
153 duplicate = owner.createElement (element.getTagName ());
154 } else {
155 duplicate = owner.createElementNS (namespace_uri, element.getTagName ());
156 }
157 // Copy element attributes
158 if (with_attributes) {
159 NamedNodeMap attributes = element.getAttributes ();
160 for (int i = 0; i < attributes.getLength (); i++) {
161 Node attribute = attributes.item (i);
162 duplicate.setAttribute (attribute.getNodeName (), attribute.getNodeValue ());
163 }
164 }
165
166 // Copy element children
167 NodeList children = element.getChildNodes ();
168 for (int i = 0; i < children.getLength (); i++) {
169 Node child = children.item (i);
170 duplicate.appendChild (owner.importNode (child, true));
171 }
172
173 return duplicate;
174 }
175
176
177 /** Remove all of the child nodes from a certain node. */
178 static final public void clear (Node node) {
179 while (node.hasChildNodes ()) {
180 node.removeChild (node.getFirstChild ());
181 }
182 }
183
184
185 static public ArrayList getChildElementsByTagName (Element parent_element, String element_name) {
186 ArrayList child_elements = new ArrayList ();
187
188 NodeList children_nodelist = parent_element.getChildNodes ();
189 for (int i = 0; i < children_nodelist.getLength (); i++) {
190 Node child_node = children_nodelist.item (i);
191 if (child_node.getNodeType () == Node.ELEMENT_NODE && child_node.getNodeName ().equals (element_name)) {
192 child_elements.add (child_node);
193 }
194 }
195
196 return child_elements;
197 }
198
199
200 static public String getElementTextValue (Element element) {
201 // Find the first text node child
202 NodeList children_nodelist = element.getChildNodes ();
203 for (int i = 0; i < children_nodelist.getLength (); i++) {
204 Node child_node = children_nodelist.item (i);
205 if (child_node.getNodeType () == Node.TEXT_NODE) {
206 return child_node.getNodeValue ();
207 }
208 }
209
210 // None found
211 return "";
212 }
213
214
215 /** Method to retrieve the value of a given node.
216 * @param element The <strong>Element</strong> whose value we wish to find.
217 * Soon to be deprecated!
218 */
219 static final public String getValue (Node element) {
220 if (element == null) {
221 return "";
222 }
223 // If we've been given a subject node first retrieve its value node.
224 if(element.getNodeName ().equals ("Subject")) {
225 element = getNodeFromNamed (element, "Value");
226 }
227 // If we've got a value node, then reconstruct the text. Remember that DOM will split text over 256 characters into several text nodes
228 if(element != null && element.hasChildNodes ()) {
229 StringBuffer text_buffer = new StringBuffer ();
230 NodeList text_nodes = element.getChildNodes ();
231 for(int i = 0; i < text_nodes.getLength (); i++) {
232 Node possible_text = text_nodes.item (i);
233 if(possible_text.getNodeName ().equals (StaticStrings.TEXT_NODE)) {
234 text_buffer.append (possible_text.getNodeValue ());
235 }
236 }
237 return text_buffer.toString ();
238 }
239 return "";
240 }
241
242
243 /** Method to retrieve from the node given, a certain child node with the specified name.
244 * @param parent The <strong>Node</strong> whose children should be searched.
245 * @param name The required nodes name as a <strong>String</strong>.
246 * @return The requested <strong>Node</strong> if it is found, <i>null</i> otherwise.
247 * Soon to be deprecated!
248 */
249 static final public Node getNodeFromNamed (Node parent, String name) {
250 Node child = null;
251 for(Node i = parent.getFirstChild (); i != null && child == null;
252 i = i.getNextSibling ()) {
253 if(i.getNodeName ().equals (name)) {
254 child = i;
255 }
256 }
257 return child;
258 }
259
260 static final public String WELLFORMED= "well-formed !";
261 static final public String NOTWELLFORMED= "not well-formed";
262 static final private String HEADER = "<?xml version='1.0' encoding='UTF-8'?><collectionConfig xmlns:gsf='http://www.greenstone.org/greenstone3/schema/ConfigFormat' xmlns:xsl='http://www.w3.org/1999/XSL/Transform'>";
263 static final private String FOOTER = "</collectionConfig>";
264
265public static String parse (String xml_str) {
266 String validation_msg = WELLFORMED;
267 xml_str = HEADER + xml_str + FOOTER;
268 try {
269 SAXParserFactory factory = SAXParserFactory.newInstance ();
270 factory.setNamespaceAware (true);
271 //factory.setValidating (true);
272 SAXParser parser = factory.newSAXParser ();
273 InputSource iSource = new InputSource ( new StringReader ( xml_str ) );
274// parser.parse (iSource, new DefaultHandler ());
275
276 org.xml.sax.XMLReader reader = parser.getXMLReader ();
277 reader.setContentHandler(new DefaultHandler());
278 reader.setErrorHandler(new DefaultHandler());
279 reader.parse(iSource);
280 } catch (FactoryConfigurationError e) {
281 validation_msg = "unable to get a document builder factory";
282 } catch (ParserConfigurationException e) {
283 validation_msg = "unable to configure parser";
284 } catch (SAXParseException e) {
285 validation_msg = NOTWELLFORMED + getLocationString(e) + e.getMessage ();
286 } catch (SAXException e) {
287 validation_msg += " Fatal error: " + e.toString ();
288 } catch (IOException e) {
289 validation_msg = "Unable to read the input, i/o error";
290 }
291
292 return validation_msg;
293 }
294//In this method, the parsed string xml_str is not wrapped by the header and footer strings.
295public static String parseDOM (String xml_str) {
296 String validation_msg = WELLFORMED;
297
298 try {
299 SAXParserFactory factory = SAXParserFactory.newInstance ();
300 factory.setNamespaceAware (true);
301 //factory.setValidating (true);
302 SAXParser parser = factory.newSAXParser ();
303 InputSource iSource = new InputSource ( new StringReader ( xml_str ) );
304// parser.parse (iSource, new DefaultHandler ());
305
306 org.xml.sax.XMLReader reader = parser.getXMLReader ();
307 reader.setContentHandler(new DefaultHandler());
308 reader.setErrorHandler(new DefaultHandler());
309 reader.parse(iSource);
310 } catch (FactoryConfigurationError e) {
311 validation_msg = "unable to get a document builder factory";
312 } catch (ParserConfigurationException e) {
313 validation_msg = "unable to configure parser";
314 } catch (SAXParseException e) {
315 validation_msg = NOTWELLFORMED + getLocationString(e) + e.getMessage ();
316 } catch (SAXException e) {
317 validation_msg += " " + e.toString ();
318 } catch (IOException e) {
319 validation_msg = "Unable to read the input, i/o error";
320 }
321
322 return validation_msg;
323 }
324
325public static String parse (File xml_file) {
326 String validation_msg = WELLFORMED;
327
328 try {
329 SAXParserFactory factory = SAXParserFactory.newInstance ();
330 factory.setNamespaceAware (true);
331 //factory.setValidating (true);
332 SAXParser parser = factory.newSAXParser ();
333 FileReader r = new FileReader(xml_file);
334 InputSource iSource = new InputSource(r);
335 XMLReader reader = parser.getXMLReader ();
336 reader.setContentHandler(new DefaultHandler());
337 reader.setErrorHandler(new DefaultHandler());
338 reader.parse(iSource);
339 } catch (FactoryConfigurationError e) {
340 validation_msg = "unable to get a document builder factory";
341 } catch (ParserConfigurationException e) {
342 validation_msg = "unable to configure parser";
343 } catch (SAXParseException e) {
344 validation_msg = NOTWELLFORMED + getLocationString(e) + e.getMessage ();
345 } catch (SAXException e) {
346 validation_msg += " Fatal error: " + e.toString ();
347 } catch (IOException e) {
348 validation_msg = "Unable to read the input, i/o error";
349 }
350
351 return validation_msg;
352 }
353 /** Returns a string of the location. */
354 private static String getLocationString(SAXParseException ex) {
355 StringBuffer str = new StringBuffer();
356
357 String systemId = ex.getSystemId();
358 if (systemId != null) {
359 int index = systemId.lastIndexOf('/');
360 if (index != -1)
361 systemId = systemId.substring(index + 1);
362 str.append(systemId);
363 }
364 str.append("(line ");
365 str.append(ex.getLineNumber()-1);
366 str.append(", column ");
367 str.append(ex.getColumnNumber());
368 str.append("): ");
369
370 return str.toString();
371
372 } // getLocationString(SAXParseException):String
373
374
375 /** Parse an XML document from a given file path */
376 static public Document parseXMLFile (String xml_file_path, boolean use_class_loader) {
377 if (use_class_loader == true) {
378 InputStream is = JarTools.getResourceAsStream ("/" + xml_file_path);
379 if (is != null) {
380 return parseXML (is);
381 }
382 }
383
384 // Try the file outside the classes directory
385 return parseXMLFile (new File (xml_file_path));
386 }
387
388
389 /** Parse an XML document from a given file */
390 static public Document parseXMLFile (File xml_file) {
391 // No file? No point trying!
392 if (xml_file.exists () == false) {
393 return null;
394 }
395
396 try {
397 return parseXML (new FileInputStream (xml_file));
398 }
399 catch (Exception exception) {
400 DebugStream.printStackTrace (exception);
401 return null;
402 }
403 }
404
405
406 /** Parse an XML document from a given input stream */
407 static public Document parseXML (InputStream xml_input_stream) {
408 Document document = null;
409
410 try {
411 InputStreamReader isr = new InputStreamReader (xml_input_stream, "UTF-8");
412 Reader xml_reader = new BufferedReader (isr);
413 document = parseXML (xml_reader);
414 isr.close ();
415 xml_input_stream.close ();
416 }
417 catch (Exception exception) {
418 DebugStream.printStackTrace (exception);
419 }
420
421 return document;
422 }
423
424
425 /** Parse an XML document from a given reader */
426 static public Document parseXML (Reader xml_reader) {
427 // If debugging, the following will store the XML contents to be parsed,
428 // which can then be inspected upon encountering a SAXException (need to run GLI with -debug on)
429 String xmlContents = "";
430
431 Document document = null;
432 try {
433 // (1) In case parsing exceptions are thrown (SAX Exceptions), we want to get some
434 // idea of where things went wrong. This will print the "XML" contents to either
435 // system.out (if debugging is off) or to the DebugStream otherwise.
436 // We need to read the XML twice to know the line where things went wrong, so
437 // do the additional reading only if we're debugging
438 if(DebugStream.isDebuggingEnabled()) {
439 StringBuffer buf = new StringBuffer();
440 char[] buffer = new char[500];
441 int numCharsRead = xml_reader.read(buffer, 0, buffer.length);
442 while(numCharsRead != -1) {
443 buf.append(buffer, 0, numCharsRead);
444 numCharsRead = xml_reader.read(buffer, 0, buffer.length);
445 }
446 xmlContents = buf.toString();
447 xml_reader.close(); // closing the old Reader
448 xml_reader = null;
449 buffer = null;
450 buf = null;
451 // we need a Reader to parse the same contents as the Reader that was just closed
452 xml_reader = new StringReader(xmlContents);
453 }
454
455 // (2) The actual XML parsing
456 InputSource isc = new InputSource (xml_reader);
457 DOMParser parser = new DOMParser ();
458 parser.setFeature ("http://xml.org/sax/features/validation", false);
459 parser.setFeature ("http://apache.org/xml/features/nonvalidating/load-external-dtd", false);
460 // May or may not be ignored, the documentation for Xerces is contradictory. If it works then parsing -should- be faster.
461 parser.setFeature ("http://apache.org/xml/features/dom/defer-node-expansion", true);
462 parser.setFeature ("http://apache.org/xml/features/dom/include-ignorable-whitespace", false);
463 parser.parse (isc);
464 document = parser.getDocument ();
465
466 } catch(SAXParseException e) {
467 showXMLParseFailureLine(e, xmlContents);
468 } catch (SAXException exception) {
469 System.err.println ("SAX exception: " + exception.getMessage ());
470 if(DebugStream.isDebuggingEnabled()) {
471 DebugStream.println("Encountered a SAX exception when parsing the following:\n*********START\n"
472 + xmlContents + "\n************END\n");
473 // Exit to let the user view the erroneous line/xml before it goes past the screen buffer?
474 DebugStream.println("Debug mode: Exiting the program as there was trouble parsing the XML...");
475 System.exit(-1);
476 }
477 // else, not running in debug mode, so don't exit after exception
478 System.out.println("***Turn debugging on (run GLI with -debug) to view the XML contents that could not be parsed.");
479 DebugStream.printStackTrace (exception);
480 }
481 catch (Exception exception) {
482 DebugStream.printStackTrace (exception);
483 }
484
485 return document;
486 }
487
488 /** Displays the line (string) where the SAXParseException occurred, given a String of the
489 * entire xml that was being parsed and the SAXParseException object that was caught.
490 * The messages are printed to DebugStream, so run GLI/FLI with -debug to view this output.
491 * @param xmlContents is the entire xml that was being parsed when the exception occurred
492 * @param e is the SAXParseException object that was thrown upon parsing the xmlContents.
493 */
494 public static void showXMLParseFailureLine(SAXParseException e, String xmlContents) {
495
496 // There should be no characters at all that preceed the <?xml>... bit.
497 // The first check is for starting spaces:
498 if(xmlContents.startsWith("\n") || xmlContents.startsWith(" ") || xmlContents.startsWith("\t")) {
499 DebugStream.println("ERROR: illegal start of XML. Space/tab/newline should not preceed xml declaration.\n");
500 DebugStream.println("xmlContents (length is " + xmlContents.length() + "):\n" + xmlContents);
501 return; // nothing more to do, first error identified
502 }
503
504 // the actual line (String literal) where parsing failed and the SAXParseException occurred.
505 String line = "";
506 int linenumber = e.getLineNumber();
507 DebugStream.println("\n****SAXParseException on LINE NUMBER: " + linenumber);
508 if(DebugStream.isDebuggingEnabled()) {
509 if(linenumber != -1) {
510 // find the line in xmlContents string (xmlContents is only set if GLI is run with debugging turned on)
511 int start = 0;
512 int end = xmlContents.length();
513 for(int i = 1; i <= linenumber; i++) {
514 end = xmlContents.indexOf("\n");
515 if(end > 0) {
516 line = xmlContents.substring(start, end);
517 }
518 start = end+1;
519 }
520 DebugStream.println("The parsing error occurred on this line:\n***********START\n" + line + "\n***********END");
521 DebugStream.println("SAXParseException message: " + e.getMessage() + "\n");
522 } else { // no particular line number, print out all the xml so debugger can inspect it
523 DebugStream.println("Encountered a SAX exception when parsing the following:\n*********START\n"
524 + xmlContents + "\n************END\n");
525 }
526 // Exit to let the user view the erroneous line/xml before it goes past the screen buffer?
527 DebugStream.println("\nDebug mode: Exiting the program as there was trouble parsing the XML...");
528 System.exit(-1);
529 } else { // not running in debug mode
530 System.out.println("***Turn debugging on (run GLI with -debug) to view the XML contents/line that could not be parsed.");
531 }
532 }
533
534
535 static public StringBuffer readXMLStream (InputStream input_stream) {
536 StringBuffer xml = new StringBuffer ("");
537
538 try {
539 InputStreamReader isr = new InputStreamReader (input_stream, "UTF-8");
540 BufferedReader buffered_in = new BufferedReader (isr);
541
542 String line = "";
543 boolean xml_content = false;
544 while((line = buffered_in.readLine ()) != null) {
545 if(xml_content) {
546 xml.append (line);
547 xml.append ("\n");
548 }
549 else if(line.trim ().startsWith ("<?xml")) {
550 xml_content = true;
551 xml.append (line);
552 xml.append ("\n");
553 }
554 }
555 buffered_in = null;
556 }
557 catch (Exception error) {
558 System.err.println ("Failed when trying to parse XML stream");
559 error.printStackTrace ();
560 }
561
562 return xml;
563 }
564
565
566 /** Removes characters that are invalid in XML (see http://www.w3.org/TR/2000/REC-xml-20001006#charsets) */
567 static public String removeInvalidCharacters (String text) {
568 char[] safe_characters = new char[text.length ()];
569 int j = 0;
570
571 char[] raw_characters = new char[text.length ()];
572 text.getChars (0, text.length (), raw_characters, 0);
573 for (int i = 0; i < raw_characters.length; i++) {
574 char character = raw_characters[i];
575 if ((character >= 0x20 && character <= 0xD7FF) || character == 0x09 || character == 0x0A || character == 0x0D || (character >= 0xE000 && character <= 0xFFFD) || (character >= 0x10000 && character <= 0x10FFFF)) {
576 safe_characters[j] = character;
577 j++;
578 }
579 }
580
581 return new String (safe_characters, 0, j);
582 }
583
584
585 static public void setElementTextValue (Element element, String text) {
586 // Remove all text node children
587 NodeList children_nodelist = element.getChildNodes ();
588 for (int i = children_nodelist.getLength () - 1; i >= 0; i--) {
589 Node child_node = children_nodelist.item (i);
590 if (child_node.getNodeType () == Node.TEXT_NODE) {
591 element.removeChild (child_node);
592 }
593 }
594
595 // Add a new text node
596 if (text != null) {
597 element.appendChild (element.getOwnerDocument ().createTextNode (text));
598 }
599 }
600
601
602 /** Set the #text node value of some element.
603 * @param element the Element whose value we wish to set
604 * @param value the new value for the element as a String
605 * Soon to be deprecated!
606 */
607 static final public void setValue (Element element, String value) {
608 // Remove any existing child node(s)
609 clear (element);
610 // Add new text node.
611 if (value != null) {
612 element.appendChild (element.getOwnerDocument ().createTextNode (value));
613 }
614 }
615
616 /** Write an XML document to a given file with the text node of the specified element unescaped*/
617 static public void writeXMLFile (File xml_file, Document document, String[] nonEscapingTagNames) {
618 try {
619 OutputStream os = new FileOutputStream (xml_file);
620 // Create an output format for our document.
621 OutputFormat f = new OutputFormat (document);
622 f.setEncoding ("UTF-8");
623 f.setIndenting (true);
624 f.setLineWidth (0); // Why isn't this working!
625 f.setPreserveSpace (false);
626
627 f.setNonEscapingElements (nonEscapingTagNames);
628 // Create the necessary writer stream for serialization.
629 OutputStreamWriter osw = new OutputStreamWriter (os, "UTF-8");
630 Writer w = new BufferedWriter (osw);
631 // Generate a new serializer from the above.
632 XMLSerializer s = new XMLSerializer (w, f);
633 s.asDOMSerializer ();
634 // Finally serialize the document to file.
635 s.serialize (document);
636 // And close.
637 os.close ();
638 }
639 catch (Exception exception) {
640 DebugStream.printStackTrace (exception);
641 }
642 }
643
644 /** Write an XML document to a given file */
645 static public void writeXMLFile (File xml_file, Document document) {
646 try {
647 OutputStream os = new FileOutputStream (xml_file);
648 // Create an output format for our document.
649 OutputFormat f = new OutputFormat (document);
650 f.setEncoding ("UTF-8");
651 f.setIndenting (true);
652 f.setLineWidth (0); // Why isn't this working!
653 f.setPreserveSpace (false);
654 // Create the necessary writer stream for serialization.
655 OutputStreamWriter osw = new OutputStreamWriter (os, "UTF-8");
656 Writer w = new BufferedWriter (osw);
657 // Generate a new serializer from the above.
658 XMLSerializer s = new XMLSerializer (w, f);
659 s.asDOMSerializer ();
660 // Finally serialize the document to file.
661 s.serialize (document);
662 // And close.
663 os.close ();
664 }
665 catch (Exception exception) {
666 DebugStream.printStackTrace (exception);
667 }
668 }
669
670 public static void printXMLNode (Node e) {
671 printXMLNode (e, 0) ;
672 }
673
674 public static void printXMLNode (Node e, int depth) { //recursive method call using DOM API...
675
676 for (int i=0 ; i<depth ; i++)
677 System.out.print (' ') ;
678
679 if (e.getNodeType () == Node.TEXT_NODE){
680 //System.out.println("text") ;
681 if (e.getNodeValue () != "") {
682 System.out.println (e.getNodeValue ()) ;
683 }
684 return ;
685 }
686
687 System.out.print ('<');
688 System.out.print (e.getNodeName ());
689 NamedNodeMap attrs = e.getAttributes ();
690 if (attrs != null) {
691 for (int i = 0; i < attrs.getLength (); i++) {
692 Node attr = attrs.item (i);
693 System.out.print (' ');
694 System.out.print (attr.getNodeName ());
695 System.out.print ("=\"");
696 System.out.print (attr.getNodeValue ());
697 System.out.print ('"');
698 }
699 }
700 NodeList children = e.getChildNodes ();
701
702 if (children == null || children.getLength () == 0)
703 System.out.println ("/>") ;
704 else {
705
706 System.out.println ('>') ;
707
708 int len = children.getLength ();
709 for (int i = 0; i < len; i++) {
710 printXMLNode (children.item (i), depth + 1);
711 }
712
713 for (int i=0 ; i<depth ; i++)
714 System.out.print (' ') ;
715
716 System.out.println ("</" + e.getNodeName () + ">");
717 }
718
719 }
720 public static String xmlNodeToString (Node e){
721 StringBuffer sb = new StringBuffer ("");
722 xmlNodeToString (sb,e,0);
723 return sb.toString ();
724 }
725
726 private static void xmlNodeToString (StringBuffer sb, Node e, int depth){
727
728 for (int i=0 ; i<depth ; i++)
729 sb.append (' ') ;
730
731 if (e.getNodeType () == Node.TEXT_NODE){
732 if (e.getNodeValue () != "") {
733 sb.append (e.getNodeValue ()) ;
734 }
735 return ;
736 }
737
738 sb.append ('<');
739 sb.append (e.getNodeName ());
740 NamedNodeMap attrs = e.getAttributes ();
741 if (attrs != null) {
742 for (int i = 0; i < attrs.getLength (); i++) {
743 Node attr = attrs.item (i);
744 sb.append (' ');
745 sb.append (attr.getNodeName ());
746 sb.append ("=\"");
747 sb.append (attr.getNodeValue ());
748 sb.append ('"');
749 }
750 }
751 NodeList children = e.getChildNodes ();
752
753 if (children == null || children.getLength () == 0)
754 sb.append ("/>\n") ;
755 else {
756
757 sb.append (">\n") ;
758
759 int len = children.getLength ();
760 for (int i = 0; i < len; i++) {
761 xmlNodeToString (sb,children.item (i), depth + 1);
762 }
763
764 for (int i=0 ; i<depth ; i++)
765 sb.append (' ') ;
766
767 sb.append ("</" + e.getNodeName () + ">\n");
768 }
769
770
771 }
772 public static String xmlNodeToStringWithoutNewline (Node e){
773 StringBuffer sb = new StringBuffer ("");
774 xmlNodeToStringWithoutNewline (sb,e,0);
775 return sb.toString ();
776 }
777
778 private static void xmlNodeToStringWithoutNewline (StringBuffer sb, Node e, int depth){
779
780 for (int i=0 ; i<depth ; i++)
781 sb.append (' ') ;
782
783 if (e.getNodeType () == Node.TEXT_NODE){
784 if (e.getNodeValue () != "") {
785 sb.append (e.getNodeValue ()) ;
786 }
787 return ;
788 }
789
790 sb.append ('<');
791 sb.append (e.getNodeName ());
792 NamedNodeMap attrs = e.getAttributes ();
793 if (attrs != null) {
794 for (int i = 0; i < attrs.getLength (); i++) {
795 Node attr = attrs.item (i);
796 sb.append (' ');
797 sb.append (attr.getNodeName ());
798 sb.append ("=\"");
799 sb.append (attr.getNodeValue ());
800 sb.append ('"');
801 }
802 }
803 NodeList children = e.getChildNodes ();
804
805 if (children == null || children.getLength () == 0)
806 sb.append ("/>") ;
807 else {
808
809 sb.append (">") ;
810
811 int len = children.getLength ();
812 for (int i = 0; i < len; i++) {
813 xmlNodeToStringWithoutNewline (sb,children.item (i), depth + 1);
814 }
815
816 for (int i=0 ; i<depth ; i++)
817 sb.append (' ') ;
818
819 sb.append ("</" + e.getNodeName () + ">");
820 }
821 }
822}
Note: See TracBrowser for help on using the repository browser.