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

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

Changed method parseXML(Reader r) to tell us where XML parsing went wrong, as long as GLI/FLI is run with -debug. Added method showXMLParseFailureLine to show the textual contents of the line where parsing failed, also when GLI/FLI is run with -debug.

  • Property svn:keywords set to Author Date Id Revision
File size: 31.5 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 // the actual line (String literal) where parsing failed and the SAXParseException occurred.
496 String line = "";
497 int linenumber = e.getLineNumber();
498 DebugStream.println("\n****SAXParseException on LINE NUMBER: " + linenumber);
499 if(DebugStream.isDebuggingEnabled()) {
500 if(linenumber != -1) {
501 // find the line in xmlContents string (xmlContents is only set if GLI is run with debugging turned on)
502 int start = 0;
503 int end = xmlContents.length();
504 for(int i = 1; i <= linenumber; i++) {
505 end = xmlContents.indexOf("\n");
506 line = xmlContents.substring(start, end);
507 start = end+1;
508 }
509 DebugStream.println("The parsing error occurred on this line:\n***********START\n" + line + "\n***********END");
510 DebugStream.println("SAXParseException message: " + e.getMessage() + "\n");
511 } else { // no particular line number, print out all the xml so debugger can inspect it
512 DebugStream.println("Encountered a SAX exception when parsing the following:\n*********START\n"
513 + xmlContents + "\n************END\n");
514 }
515 // Exit to let the user view the erroneous line/xml before it goes past the screen buffer?
516 DebugStream.println("\nDebug mode: Exiting the program as there was trouble parsing the XML...");
517 System.exit(-1);
518 } else { // not running in debug mode
519 System.out.println("***Turn debugging on (run GLI with -debug) to view the XML contents/line that could not be parsed.");
520 }
521 }
522
523
524 static public StringBuffer readXMLStream (InputStream input_stream) {
525 StringBuffer xml = new StringBuffer ("");
526
527 try {
528 InputStreamReader isr = new InputStreamReader (input_stream, "UTF-8");
529 BufferedReader buffered_in = new BufferedReader (isr);
530
531 String line = "";
532 boolean xml_content = false;
533 while((line = buffered_in.readLine ()) != null) {
534 if(xml_content) {
535 xml.append (line);
536 xml.append ("\n");
537 }
538 else if(line.trim ().startsWith ("<?xml")) {
539 xml_content = true;
540 xml.append (line);
541 xml.append ("\n");
542 }
543 }
544 buffered_in = null;
545 }
546 catch (Exception error) {
547 System.err.println ("Failed when trying to parse XML stream");
548 error.printStackTrace ();
549 }
550
551 return xml;
552 }
553
554
555 /** Removes characters that are invalid in XML (see http://www.w3.org/TR/2000/REC-xml-20001006#charsets) */
556 static public String removeInvalidCharacters (String text) {
557 char[] safe_characters = new char[text.length ()];
558 int j = 0;
559
560 char[] raw_characters = new char[text.length ()];
561 text.getChars (0, text.length (), raw_characters, 0);
562 for (int i = 0; i < raw_characters.length; i++) {
563 char character = raw_characters[i];
564 if ((character >= 0x20 && character <= 0xD7FF) || character == 0x09 || character == 0x0A || character == 0x0D || (character >= 0xE000 && character <= 0xFFFD) || (character >= 0x10000 && character <= 0x10FFFF)) {
565 safe_characters[j] = character;
566 j++;
567 }
568 }
569
570 return new String (safe_characters, 0, j);
571 }
572
573
574 static public void setElementTextValue (Element element, String text) {
575 // Remove all text node children
576 NodeList children_nodelist = element.getChildNodes ();
577 for (int i = children_nodelist.getLength () - 1; i >= 0; i--) {
578 Node child_node = children_nodelist.item (i);
579 if (child_node.getNodeType () == Node.TEXT_NODE) {
580 element.removeChild (child_node);
581 }
582 }
583
584 // Add a new text node
585 if (text != null) {
586 element.appendChild (element.getOwnerDocument ().createTextNode (text));
587 }
588 }
589
590
591 /** Set the #text node value of some element.
592 * @param element the Element whose value we wish to set
593 * @param value the new value for the element as a String
594 * Soon to be deprecated!
595 */
596 static final public void setValue (Element element, String value) {
597 // Remove any existing child node(s)
598 clear (element);
599 // Add new text node.
600 if (value != null) {
601 element.appendChild (element.getOwnerDocument ().createTextNode (value));
602 }
603 }
604
605 /** Write an XML document to a given file with the text node of the specified element unescaped*/
606 static public void writeXMLFile (File xml_file, Document document, String[] nonEscapingTagNames) {
607 try {
608 OutputStream os = new FileOutputStream (xml_file);
609 // Create an output format for our document.
610 OutputFormat f = new OutputFormat (document);
611 f.setEncoding ("UTF-8");
612 f.setIndenting (true);
613 f.setLineWidth (0); // Why isn't this working!
614 f.setPreserveSpace (false);
615
616 f.setNonEscapingElements (nonEscapingTagNames);
617 // Create the necessary writer stream for serialization.
618 OutputStreamWriter osw = new OutputStreamWriter (os, "UTF-8");
619 Writer w = new BufferedWriter (osw);
620 // Generate a new serializer from the above.
621 XMLSerializer s = new XMLSerializer (w, f);
622 s.asDOMSerializer ();
623 // Finally serialize the document to file.
624 s.serialize (document);
625 // And close.
626 os.close ();
627 }
628 catch (Exception exception) {
629 DebugStream.printStackTrace (exception);
630 }
631 }
632
633 /** Write an XML document to a given file */
634 static public void writeXMLFile (File xml_file, Document document) {
635 try {
636 OutputStream os = new FileOutputStream (xml_file);
637 // Create an output format for our document.
638 OutputFormat f = new OutputFormat (document);
639 f.setEncoding ("UTF-8");
640 f.setIndenting (true);
641 f.setLineWidth (0); // Why isn't this working!
642 f.setPreserveSpace (false);
643 // Create the necessary writer stream for serialization.
644 OutputStreamWriter osw = new OutputStreamWriter (os, "UTF-8");
645 Writer w = new BufferedWriter (osw);
646 // Generate a new serializer from the above.
647 XMLSerializer s = new XMLSerializer (w, f);
648 s.asDOMSerializer ();
649 // Finally serialize the document to file.
650 s.serialize (document);
651 // And close.
652 os.close ();
653 }
654 catch (Exception exception) {
655 DebugStream.printStackTrace (exception);
656 }
657 }
658
659 public static void printXMLNode (Node e) {
660 printXMLNode (e, 0) ;
661 }
662
663 public static void printXMLNode (Node e, int depth) { //recursive method call using DOM API...
664
665 for (int i=0 ; i<depth ; i++)
666 System.out.print (' ') ;
667
668 if (e.getNodeType () == Node.TEXT_NODE){
669 //System.out.println("text") ;
670 if (e.getNodeValue () != "") {
671 System.out.println (e.getNodeValue ()) ;
672 }
673 return ;
674 }
675
676 System.out.print ('<');
677 System.out.print (e.getNodeName ());
678 NamedNodeMap attrs = e.getAttributes ();
679 if (attrs != null) {
680 for (int i = 0; i < attrs.getLength (); i++) {
681 Node attr = attrs.item (i);
682 System.out.print (' ');
683 System.out.print (attr.getNodeName ());
684 System.out.print ("=\"");
685 System.out.print (attr.getNodeValue ());
686 System.out.print ('"');
687 }
688 }
689 NodeList children = e.getChildNodes ();
690
691 if (children == null || children.getLength () == 0)
692 System.out.println ("/>") ;
693 else {
694
695 System.out.println ('>') ;
696
697 int len = children.getLength ();
698 for (int i = 0; i < len; i++) {
699 printXMLNode (children.item (i), depth + 1);
700 }
701
702 for (int i=0 ; i<depth ; i++)
703 System.out.print (' ') ;
704
705 System.out.println ("</" + e.getNodeName () + ">");
706 }
707
708 }
709 public static String xmlNodeToString (Node e){
710 StringBuffer sb = new StringBuffer ("");
711 xmlNodeToString (sb,e,0);
712 return sb.toString ();
713 }
714
715 private static void xmlNodeToString (StringBuffer sb, Node e, int depth){
716
717 for (int i=0 ; i<depth ; i++)
718 sb.append (' ') ;
719
720 if (e.getNodeType () == Node.TEXT_NODE){
721 if (e.getNodeValue () != "") {
722 sb.append (e.getNodeValue ()) ;
723 }
724 return ;
725 }
726
727 sb.append ('<');
728 sb.append (e.getNodeName ());
729 NamedNodeMap attrs = e.getAttributes ();
730 if (attrs != null) {
731 for (int i = 0; i < attrs.getLength (); i++) {
732 Node attr = attrs.item (i);
733 sb.append (' ');
734 sb.append (attr.getNodeName ());
735 sb.append ("=\"");
736 sb.append (attr.getNodeValue ());
737 sb.append ('"');
738 }
739 }
740 NodeList children = e.getChildNodes ();
741
742 if (children == null || children.getLength () == 0)
743 sb.append ("/>\n") ;
744 else {
745
746 sb.append (">\n") ;
747
748 int len = children.getLength ();
749 for (int i = 0; i < len; i++) {
750 xmlNodeToString (sb,children.item (i), depth + 1);
751 }
752
753 for (int i=0 ; i<depth ; i++)
754 sb.append (' ') ;
755
756 sb.append ("</" + e.getNodeName () + ">\n");
757 }
758
759
760 }
761 public static String xmlNodeToStringWithoutNewline (Node e){
762 StringBuffer sb = new StringBuffer ("");
763 xmlNodeToStringWithoutNewline (sb,e,0);
764 return sb.toString ();
765 }
766
767 private static void xmlNodeToStringWithoutNewline (StringBuffer sb, Node e, int depth){
768
769 for (int i=0 ; i<depth ; i++)
770 sb.append (' ') ;
771
772 if (e.getNodeType () == Node.TEXT_NODE){
773 if (e.getNodeValue () != "") {
774 sb.append (e.getNodeValue ()) ;
775 }
776 return ;
777 }
778
779 sb.append ('<');
780 sb.append (e.getNodeName ());
781 NamedNodeMap attrs = e.getAttributes ();
782 if (attrs != null) {
783 for (int i = 0; i < attrs.getLength (); i++) {
784 Node attr = attrs.item (i);
785 sb.append (' ');
786 sb.append (attr.getNodeName ());
787 sb.append ("=\"");
788 sb.append (attr.getNodeValue ());
789 sb.append ('"');
790 }
791 }
792 NodeList children = e.getChildNodes ();
793
794 if (children == null || children.getLength () == 0)
795 sb.append ("/>") ;
796 else {
797
798 sb.append (">") ;
799
800 int len = children.getLength ();
801 for (int i = 0; i < len; i++) {
802 xmlNodeToStringWithoutNewline (sb,children.item (i), depth + 1);
803 }
804
805 for (int i=0 ; i<depth ; i++)
806 sb.append (' ') ;
807
808 sb.append ("</" + e.getNodeName () + ">");
809 }
810 }
811}
Note: See TracBrowser for help on using the repository browser.