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

Last change on this file since 21548 was 21548, checked in by ak19, 14 years ago

Added a statement to print out all the XML when there's a parse errorr: it could be helpful with debugging, but not always, so it's commented out.

  • Property svn:keywords set to Author Date Id Revision
File size: 31.9 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 document = parseXML(isr);
413 isr.close ();
414 xml_input_stream.close ();
415 }
416 catch (Exception exception) {
417 DebugStream.printStackTrace (exception);
418 }
419
420 return document;
421 }
422
423
424 /** Parse an XML document from a given reader */
425 static public Document parseXML (Reader xml_reader) {
426 Document document = null;
427
428 // If debugging, the following will store the XML contents to be parsed,
429 // which can then be inspected upon encountering a SAXException (need to run GLI with -debug on)
430 String xmlContents = "";
431
432 try {
433 Reader reader = null;
434
435 // (1) By default, GLI will remove any contents preceeding (and invalidating)
436 // the XML and present these lines separately to the user
437 if(!DebugStream.isDebuggingEnabled()) {
438 try {
439 reader = new BufferedReader( new RemoveContentBeforeRootElementXMLReader(xml_reader) );
440 } catch ( Exception e ) {
441 System.err.println( "Exception while wrapping the reader in parseXML(Reader)" );
442 e.printStackTrace();
443 }
444 }
445
446 // (2) If we are running GLI in debug mode:
447 // In case parsing exceptions are thrown (SAX Exceptions), we want to get some
448 // idea of where things went wrong. This will print the "XML" contents to either
449 // system.out (if debugging is off) or to the DebugStream otherwise.
450 // We need to read the XML twice to know the line where things went wrong, so
451 // do the additional reading only if we're debugging
452 else {
453 StringBuffer buf = new StringBuffer();
454 char[] buffer = new char[500];
455 int numCharsRead = xml_reader.read(buffer, 0, buffer.length);
456 while(numCharsRead != -1) {
457 buf.append(buffer, 0, numCharsRead);
458 numCharsRead = xml_reader.read(buffer, 0, buffer.length);
459 }
460 xmlContents = buf.toString();
461 xml_reader.close(); // closing the old Reader
462 xml_reader = null;
463 buffer = null;
464 buf = null;
465 // we need a Reader to parse the same contents as the Reader that was just closed
466 reader = new BufferedReader(new StringReader(xmlContents));
467 //System.err.println("xmlContents:\n" + xmlContents);
468 }
469
470 // (2) The actual XML parsing
471 InputSource isc = new InputSource (reader);
472 DOMParser parser = new DOMParser ();
473 parser.setFeature ("http://xml.org/sax/features/validation", false);
474 parser.setFeature ("http://apache.org/xml/features/nonvalidating/load-external-dtd", false);
475 // May or may not be ignored, the documentation for Xerces is contradictory. If it works then parsing -should- be faster.
476 parser.setFeature ("http://apache.org/xml/features/dom/defer-node-expansion", true);
477 parser.setFeature ("http://apache.org/xml/features/dom/include-ignorable-whitespace", false);
478 parser.parse (isc);
479 document = parser.getDocument ();
480
481 } catch(SAXParseException e) {
482 showXMLParseFailureLine(e, xmlContents);
483 } catch (SAXException exception) {
484 System.err.println ("SAX exception: " + exception.getMessage ());
485 if(DebugStream.isDebuggingEnabled()) {
486 DebugStream.println("Encountered a SAX exception when parsing the following:\n*********START\n"
487 + xmlContents + "\n************END\n");
488 // Exit to let the user view the erroneous line/xml before it goes past the screen buffer?
489 DebugStream.println("Debug mode: Exiting the program as there was trouble parsing the XML...");
490 System.exit(-1);
491 }
492 // else, not running in debug mode, so don't exit after exception
493 System.out.println("***Turn debugging on (run GLI with -debug) to view the XML contents that could not be parsed.");
494 DebugStream.printStackTrace (exception);
495 }
496 catch (Exception exception) {
497 DebugStream.printStackTrace (exception);
498 }
499
500 return document;
501 }
502
503 /** Displays the line (string) where the SAXParseException occurred, given a String of the
504 * entire xml that was being parsed and the SAXParseException object that was caught.
505 * The messages are printed to DebugStream, so run GLI/FLI with -debug to view this output.
506 * @param xmlContents is the entire xml that was being parsed when the exception occurred
507 * @param e is the SAXParseException object that was thrown upon parsing the xmlContents.
508 */
509 public static void showXMLParseFailureLine(SAXParseException e, String xmlContents) {
510
511 // There should be no characters at all that preceed the <?xml>... bit.
512 // The first check is for starting spaces:
513 if(xmlContents.startsWith("\n") || xmlContents.startsWith(" ") || xmlContents.startsWith("\t")) {
514 DebugStream.println("ERROR: illegal start of XML. Space/tab/newline should not preceed xml declaration.\n");
515 DebugStream.println("xmlContents (length is " + xmlContents.length() + "):\n" + xmlContents);
516 return; // nothing more to do, first error identified
517 }
518
519 // the actual line (String literal) where parsing failed and the SAXParseException occurred.
520 String line = "";
521 int linenumber = e.getLineNumber();
522 DebugStream.print("\n****SAXParseException on LINE NUMBER: " + linenumber);
523 if(DebugStream.isDebuggingEnabled()) {
524 if(linenumber != -1) {
525 String[] lines = xmlContents.split("\n");
526 if (lines.length > 0) {
527 DebugStream.println(" (number of lines: " + lines.length + ")");
528 if(lines.length >= linenumber) {
529 line = lines[linenumber-1];
530 } else { // error is past the last line
531 line = "Error is past the last line (" + lines.length + "): " + lines[lines.length-1];
532 }
533 } else {
534 DebugStream.print("\n");
535 }
536 lines = null;
537
538 DebugStream.println("The parsing error occurred on this line:\n***********START\n" + line + "\n***********END");
539 DebugStream.println("SAXParseException message: " + e.getMessage() + "\n");
540
541 // Uncomment if you want to print out the entire contents of the XML doc:
542 //DebugStream.println("\n\nThis was the XML:\n*********START\n"
543 // + xmlContents + "\n************END\n");
544 } else { // no particular line number, print out all the xml so debugger can inspect it
545 DebugStream.println("Encountered a SAX exception when parsing the following:\n*********START\n"
546 + xmlContents + "\n************END\n");
547 }
548 // Exit to let the user view the erroneous line/xml before it goes past the screen buffer?
549 DebugStream.println("\nDebug mode: Exiting the program as there was trouble parsing the XML...");
550 System.exit(-1);
551 } else { // not running in debug mode
552 System.out.println("***Turn debugging on (run GLI with -debug) to view the XML contents/line that could not be parsed.");
553 }
554 }
555
556
557 static public StringBuffer readXMLStream (InputStream input_stream) {
558 StringBuffer xml = new StringBuffer ("");
559
560 try {
561 InputStreamReader isr = new InputStreamReader (input_stream, "UTF-8");
562 BufferedReader buffered_in = new BufferedReader (isr);
563
564 String line = "";
565 boolean xml_content = false;
566 while((line = buffered_in.readLine ()) != null) {
567 if(xml_content) {
568 xml.append (line);
569 xml.append ("\n");
570 }
571 else if(line.trim ().startsWith ("<?xml")) {
572 xml_content = true;
573 xml.append (line);
574 xml.append ("\n");
575 }
576 }
577 buffered_in = null;
578 }
579 catch (Exception error) {
580 System.err.println ("Failed when trying to parse XML stream");
581 error.printStackTrace ();
582 }
583
584 return xml;
585 }
586
587
588 /** Removes characters that are invalid in XML (see http://www.w3.org/TR/2000/REC-xml-20001006#charsets) */
589 static public String removeInvalidCharacters (String text) {
590 char[] safe_characters = new char[text.length ()];
591 int j = 0;
592
593 char[] raw_characters = new char[text.length ()];
594 text.getChars (0, text.length (), raw_characters, 0);
595 for (int i = 0; i < raw_characters.length; i++) {
596 char character = raw_characters[i];
597 if ((character >= 0x20 && character <= 0xD7FF) || character == 0x09 || character == 0x0A || character == 0x0D || (character >= 0xE000 && character <= 0xFFFD) || (character >= 0x10000 && character <= 0x10FFFF)) {
598 safe_characters[j] = character;
599 j++;
600 }
601 }
602
603 return new String (safe_characters, 0, j);
604 }
605
606
607 static public void setElementTextValue (Element element, String text) {
608 // Remove all text node children
609 NodeList children_nodelist = element.getChildNodes ();
610 for (int i = children_nodelist.getLength () - 1; i >= 0; i--) {
611 Node child_node = children_nodelist.item (i);
612 if (child_node.getNodeType () == Node.TEXT_NODE) {
613 element.removeChild (child_node);
614 }
615 }
616
617 // Add a new text node
618 if (text != null) {
619 element.appendChild (element.getOwnerDocument ().createTextNode (text));
620 }
621 }
622
623
624 /** Set the #text node value of some element.
625 * @param element the Element whose value we wish to set
626 * @param value the new value for the element as a String
627 * Soon to be deprecated!
628 */
629 static final public void setValue (Element element, String value) {
630 // Remove any existing child node(s)
631 clear (element);
632 // Add new text node.
633 if (value != null) {
634 element.appendChild (element.getOwnerDocument ().createTextNode (value));
635 }
636 }
637
638 /** Write an XML document to a given file with the text node of the specified element unescaped*/
639 static public void writeXMLFile (File xml_file, Document document, String[] nonEscapingTagNames) {
640 try {
641 OutputStream os = new FileOutputStream (xml_file);
642 // Create an output format for our document.
643 OutputFormat f = new OutputFormat (document);
644 f.setEncoding ("UTF-8");
645 f.setIndenting (true);
646 f.setLineWidth (0); // Why isn't this working!
647 f.setPreserveSpace (false);
648 if (nonEscapingTagNames != null) {
649 f.setNonEscapingElements (nonEscapingTagNames);
650 }
651 // Create the necessary writer stream for serialization.
652 OutputStreamWriter osw = new OutputStreamWriter (os, "UTF-8");
653 Writer w = new BufferedWriter (osw);
654 // Generate a new serializer from the above.
655 XMLSerializer s = new XMLSerializer (w, f);
656 s.asDOMSerializer ();
657 // Finally serialize the document to file.
658 s.serialize (document);
659 // And close.
660 os.close ();
661 }
662 catch (Exception exception) {
663 DebugStream.printStackTrace (exception);
664 }
665 }
666
667 /** Write an XML document to a given file */
668 static public void writeXMLFile (File xml_file, Document document) {
669 writeXMLFile(xml_file, document, null);
670 }
671
672 public static void printXMLNode (Node e) {
673 printXMLNode (e, 0) ;
674 }
675
676 public static void printXMLNode (Node e, int depth) { //recursive method call using DOM API...
677
678 for (int i=0 ; i<depth ; i++)
679 System.out.print (' ') ;
680
681 if (e.getNodeType () == Node.TEXT_NODE){
682 //System.out.println("text") ;
683 if (e.getNodeValue () != "") {
684 System.out.println (e.getNodeValue ()) ;
685 }
686 return ;
687 }
688
689 System.out.print ('<');
690 System.out.print (e.getNodeName ());
691 NamedNodeMap attrs = e.getAttributes ();
692 if (attrs != null) {
693 for (int i = 0; i < attrs.getLength (); i++) {
694 Node attr = attrs.item (i);
695 System.out.print (' ');
696 System.out.print (attr.getNodeName ());
697 System.out.print ("=\"");
698 System.out.print (attr.getNodeValue ());
699 System.out.print ('"');
700 }
701 }
702 NodeList children = e.getChildNodes ();
703
704 if (children == null || children.getLength () == 0)
705 System.out.println ("/>") ;
706 else {
707
708 System.out.println ('>') ;
709
710 int len = children.getLength ();
711 for (int i = 0; i < len; i++) {
712 printXMLNode (children.item (i), depth + 1);
713 }
714
715 for (int i=0 ; i<depth ; i++)
716 System.out.print (' ') ;
717
718 System.out.println ("</" + e.getNodeName () + ">");
719 }
720
721 }
722 public static String xmlNodeToString (Node e){
723 StringBuffer sb = new StringBuffer ("");
724 xmlNodeToString (sb,e,0);
725 return sb.toString ();
726 }
727
728 private static void xmlNodeToString (StringBuffer sb, Node e, int depth){
729
730 for (int i=0 ; i<depth ; i++)
731 sb.append (' ') ;
732
733 if (e.getNodeType () == Node.TEXT_NODE){
734 if (e.getNodeValue () != "") {
735 sb.append (e.getNodeValue ()) ;
736 }
737 return ;
738 }
739
740 sb.append ('<');
741 sb.append (e.getNodeName ());
742 NamedNodeMap attrs = e.getAttributes ();
743 if (attrs != null) {
744 for (int i = 0; i < attrs.getLength (); i++) {
745 Node attr = attrs.item (i);
746 sb.append (' ');
747 sb.append (attr.getNodeName ());
748 sb.append ("=\"");
749 sb.append (attr.getNodeValue ());
750 sb.append ('"');
751 }
752 }
753 NodeList children = e.getChildNodes ();
754
755 if (children == null || children.getLength () == 0)
756 sb.append ("/>\n") ;
757 else {
758
759 sb.append (">\n") ;
760
761 int len = children.getLength ();
762 for (int i = 0; i < len; i++) {
763 xmlNodeToString (sb,children.item (i), depth + 1);
764 }
765
766 for (int i=0 ; i<depth ; i++)
767 sb.append (' ') ;
768
769 sb.append ("</" + e.getNodeName () + ">\n");
770 }
771
772
773 }
774
775 public static String xmlNodeToStringWithoutIndenting (Node e) {
776 StringBuffer sb = new StringBuffer ("");
777 xmlNodeToStringWithoutNewline(sb, e, -1);
778 return sb.toString();
779 }
780 public static String xmlNodeToStringWithoutNewline (Node e){
781 StringBuffer sb = new StringBuffer ("");
782 xmlNodeToStringWithoutNewline (sb,e,0);
783 return sb.toString ();
784 }
785
786 private static void xmlNodeToStringWithoutNewline (StringBuffer sb, Node e, int depth){
787
788 for (int i=0 ; i<depth ; i++)
789 sb.append (' ') ;
790
791 if (e.getNodeType () == Node.TEXT_NODE){
792 if (e.getNodeValue () != "") {
793 sb.append (e.getNodeValue ()) ;
794 }
795 return ;
796 }
797
798 sb.append ('<');
799 sb.append (e.getNodeName ());
800 NamedNodeMap attrs = e.getAttributes ();
801 if (attrs != null) {
802 for (int i = 0; i < attrs.getLength (); i++) {
803 Node attr = attrs.item (i);
804 sb.append (' ');
805 sb.append (attr.getNodeName ());
806 sb.append ("=\"");
807 sb.append (attr.getNodeValue ());
808 sb.append ('"');
809 }
810 }
811 NodeList children = e.getChildNodes ();
812
813 if (children == null || children.getLength () == 0)
814 sb.append ("/>") ;
815 else {
816
817 sb.append (">") ;
818
819 int len = children.getLength ();
820 for (int i = 0; i < len; i++) {
821 if (depth >= 0) {
822 xmlNodeToStringWithoutNewline (sb,children.item (i), depth + 1);
823 } else {
824 xmlNodeToStringWithoutNewline (sb,children.item (i), depth);
825 }
826 }
827
828 for (int i=0 ; i<depth ; i++)
829 sb.append (' ') ;
830
831 sb.append ("</" + e.getNodeName () + ">");
832 }
833 }
834}
Note: See TracBrowser for help on using the repository browser.