source: gli/branches/rtl-gli/src/org/greenstone/gatherer/util/XMLTools.java@ 18353

Last change on this file since 18353 was 18353, checked in by kjdon, 15 years ago

updated the rtl-gli branch with files from trunk. Result of a merge 14807:18318

  • Property svn:keywords set to Author Date Id Revision
File size: 31.7 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 }
468
469 // (2) The actual XML parsing
470 InputSource isc = new InputSource (reader);
471 DOMParser parser = new DOMParser ();
472 parser.setFeature ("http://xml.org/sax/features/validation", false);
473 parser.setFeature ("http://apache.org/xml/features/nonvalidating/load-external-dtd", false);
474 // May or may not be ignored, the documentation for Xerces is contradictory. If it works then parsing -should- be faster.
475 parser.setFeature ("http://apache.org/xml/features/dom/defer-node-expansion", true);
476 parser.setFeature ("http://apache.org/xml/features/dom/include-ignorable-whitespace", false);
477 parser.parse (isc);
478 document = parser.getDocument ();
479
480 } catch(SAXParseException e) {
481 showXMLParseFailureLine(e, xmlContents);
482 } catch (SAXException exception) {
483 System.err.println ("SAX exception: " + exception.getMessage ());
484 if(DebugStream.isDebuggingEnabled()) {
485 DebugStream.println("Encountered a SAX exception when parsing the following:\n*********START\n"
486 + xmlContents + "\n************END\n");
487 // Exit to let the user view the erroneous line/xml before it goes past the screen buffer?
488 DebugStream.println("Debug mode: Exiting the program as there was trouble parsing the XML...");
489 System.exit(-1);
490 }
491 // else, not running in debug mode, so don't exit after exception
492 System.out.println("***Turn debugging on (run GLI with -debug) to view the XML contents that could not be parsed.");
493 DebugStream.printStackTrace (exception);
494 }
495 catch (Exception exception) {
496 DebugStream.printStackTrace (exception);
497 }
498
499 return document;
500 }
501
502 /** Displays the line (string) where the SAXParseException occurred, given a String of the
503 * entire xml that was being parsed and the SAXParseException object that was caught.
504 * The messages are printed to DebugStream, so run GLI/FLI with -debug to view this output.
505 * @param xmlContents is the entire xml that was being parsed when the exception occurred
506 * @param e is the SAXParseException object that was thrown upon parsing the xmlContents.
507 */
508 public static void showXMLParseFailureLine(SAXParseException e, String xmlContents) {
509
510 // There should be no characters at all that preceed the <?xml>... bit.
511 // The first check is for starting spaces:
512 if(xmlContents.startsWith("\n") || xmlContents.startsWith(" ") || xmlContents.startsWith("\t")) {
513 DebugStream.println("ERROR: illegal start of XML. Space/tab/newline should not preceed xml declaration.\n");
514 DebugStream.println("xmlContents (length is " + xmlContents.length() + "):\n" + xmlContents);
515 return; // nothing more to do, first error identified
516 }
517
518 // the actual line (String literal) where parsing failed and the SAXParseException occurred.
519 String line = "";
520 int linenumber = e.getLineNumber();
521 DebugStream.println("\n****SAXParseException on LINE NUMBER: " + linenumber);
522 if(DebugStream.isDebuggingEnabled()) {
523 if(linenumber != -1) {
524 // find the line in xmlContents string (xmlContents is only set if GLI is run with debugging turned on)
525 int start = 0;
526 int end = xmlContents.length();
527 for(int i = 1; i <= linenumber; i++) {
528 end = xmlContents.indexOf("\n");
529 if(end > 0) {
530 line = xmlContents.substring(start, end);
531 }
532 start = end+1;
533 }
534 DebugStream.println("The parsing error occurred on this line:\n***********START\n" + line + "\n***********END");
535 DebugStream.println("SAXParseException message: " + e.getMessage() + "\n");
536 } else { // no particular line number, print out all the xml so debugger can inspect it
537 DebugStream.println("Encountered a SAX exception when parsing the following:\n*********START\n"
538 + xmlContents + "\n************END\n");
539 }
540 // Exit to let the user view the erroneous line/xml before it goes past the screen buffer?
541 DebugStream.println("\nDebug mode: Exiting the program as there was trouble parsing the XML...");
542 System.exit(-1);
543 } else { // not running in debug mode
544 System.out.println("***Turn debugging on (run GLI with -debug) to view the XML contents/line that could not be parsed.");
545 }
546 }
547
548
549 static public StringBuffer readXMLStream (InputStream input_stream) {
550 StringBuffer xml = new StringBuffer ("");
551
552 try {
553 InputStreamReader isr = new InputStreamReader (input_stream, "UTF-8");
554 BufferedReader buffered_in = new BufferedReader (isr);
555
556 String line = "";
557 boolean xml_content = false;
558 while((line = buffered_in.readLine ()) != null) {
559 if(xml_content) {
560 xml.append (line);
561 xml.append ("\n");
562 }
563 else if(line.trim ().startsWith ("<?xml")) {
564 xml_content = true;
565 xml.append (line);
566 xml.append ("\n");
567 }
568 }
569 buffered_in = null;
570 }
571 catch (Exception error) {
572 System.err.println ("Failed when trying to parse XML stream");
573 error.printStackTrace ();
574 }
575
576 return xml;
577 }
578
579
580 /** Removes characters that are invalid in XML (see http://www.w3.org/TR/2000/REC-xml-20001006#charsets) */
581 static public String removeInvalidCharacters (String text) {
582 char[] safe_characters = new char[text.length ()];
583 int j = 0;
584
585 char[] raw_characters = new char[text.length ()];
586 text.getChars (0, text.length (), raw_characters, 0);
587 for (int i = 0; i < raw_characters.length; i++) {
588 char character = raw_characters[i];
589 if ((character >= 0x20 && character <= 0xD7FF) || character == 0x09 || character == 0x0A || character == 0x0D || (character >= 0xE000 && character <= 0xFFFD) || (character >= 0x10000 && character <= 0x10FFFF)) {
590 safe_characters[j] = character;
591 j++;
592 }
593 }
594
595 return new String (safe_characters, 0, j);
596 }
597
598
599 static public void setElementTextValue (Element element, String text) {
600 // Remove all text node children
601 NodeList children_nodelist = element.getChildNodes ();
602 for (int i = children_nodelist.getLength () - 1; i >= 0; i--) {
603 Node child_node = children_nodelist.item (i);
604 if (child_node.getNodeType () == Node.TEXT_NODE) {
605 element.removeChild (child_node);
606 }
607 }
608
609 // Add a new text node
610 if (text != null) {
611 element.appendChild (element.getOwnerDocument ().createTextNode (text));
612 }
613 }
614
615
616 /** Set the #text node value of some element.
617 * @param element the Element whose value we wish to set
618 * @param value the new value for the element as a String
619 * Soon to be deprecated!
620 */
621 static final public void setValue (Element element, String value) {
622 // Remove any existing child node(s)
623 clear (element);
624 // Add new text node.
625 if (value != null) {
626 element.appendChild (element.getOwnerDocument ().createTextNode (value));
627 }
628 }
629
630 /** Write an XML document to a given file with the text node of the specified element unescaped*/
631 static public void writeXMLFile (File xml_file, Document document, String[] nonEscapingTagNames) {
632 try {
633 OutputStream os = new FileOutputStream (xml_file);
634 // Create an output format for our document.
635 OutputFormat f = new OutputFormat (document);
636 f.setEncoding ("UTF-8");
637 f.setIndenting (true);
638 f.setLineWidth (0); // Why isn't this working!
639 f.setPreserveSpace (false);
640 if (nonEscapingTagNames != null) {
641 f.setNonEscapingElements (nonEscapingTagNames);
642 }
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 /** Write an XML document to a given file */
660 static public void writeXMLFile (File xml_file, Document document) {
661 writeXMLFile(xml_file, document, null);
662 }
663
664 public static void printXMLNode (Node e) {
665 printXMLNode (e, 0) ;
666 }
667
668 public static void printXMLNode (Node e, int depth) { //recursive method call using DOM API...
669
670 for (int i=0 ; i<depth ; i++)
671 System.out.print (' ') ;
672
673 if (e.getNodeType () == Node.TEXT_NODE){
674 //System.out.println("text") ;
675 if (e.getNodeValue () != "") {
676 System.out.println (e.getNodeValue ()) ;
677 }
678 return ;
679 }
680
681 System.out.print ('<');
682 System.out.print (e.getNodeName ());
683 NamedNodeMap attrs = e.getAttributes ();
684 if (attrs != null) {
685 for (int i = 0; i < attrs.getLength (); i++) {
686 Node attr = attrs.item (i);
687 System.out.print (' ');
688 System.out.print (attr.getNodeName ());
689 System.out.print ("=\"");
690 System.out.print (attr.getNodeValue ());
691 System.out.print ('"');
692 }
693 }
694 NodeList children = e.getChildNodes ();
695
696 if (children == null || children.getLength () == 0)
697 System.out.println ("/>") ;
698 else {
699
700 System.out.println ('>') ;
701
702 int len = children.getLength ();
703 for (int i = 0; i < len; i++) {
704 printXMLNode (children.item (i), depth + 1);
705 }
706
707 for (int i=0 ; i<depth ; i++)
708 System.out.print (' ') ;
709
710 System.out.println ("</" + e.getNodeName () + ">");
711 }
712
713 }
714 public static String xmlNodeToString (Node e){
715 StringBuffer sb = new StringBuffer ("");
716 xmlNodeToString (sb,e,0);
717 return sb.toString ();
718 }
719
720 private static void xmlNodeToString (StringBuffer sb, Node e, int depth){
721
722 for (int i=0 ; i<depth ; i++)
723 sb.append (' ') ;
724
725 if (e.getNodeType () == Node.TEXT_NODE){
726 if (e.getNodeValue () != "") {
727 sb.append (e.getNodeValue ()) ;
728 }
729 return ;
730 }
731
732 sb.append ('<');
733 sb.append (e.getNodeName ());
734 NamedNodeMap attrs = e.getAttributes ();
735 if (attrs != null) {
736 for (int i = 0; i < attrs.getLength (); i++) {
737 Node attr = attrs.item (i);
738 sb.append (' ');
739 sb.append (attr.getNodeName ());
740 sb.append ("=\"");
741 sb.append (attr.getNodeValue ());
742 sb.append ('"');
743 }
744 }
745 NodeList children = e.getChildNodes ();
746
747 if (children == null || children.getLength () == 0)
748 sb.append ("/>\n") ;
749 else {
750
751 sb.append (">\n") ;
752
753 int len = children.getLength ();
754 for (int i = 0; i < len; i++) {
755 xmlNodeToString (sb,children.item (i), depth + 1);
756 }
757
758 for (int i=0 ; i<depth ; i++)
759 sb.append (' ') ;
760
761 sb.append ("</" + e.getNodeName () + ">\n");
762 }
763
764
765 }
766
767 public static String xmlNodeToStringWithoutIndenting (Node e) {
768 StringBuffer sb = new StringBuffer ("");
769 xmlNodeToStringWithoutNewline(sb, e, -1);
770 return sb.toString();
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 if (depth >= 0) {
814 xmlNodeToStringWithoutNewline (sb,children.item (i), depth + 1);
815 } else {
816 xmlNodeToStringWithoutNewline (sb,children.item (i), depth);
817 }
818 }
819
820 for (int i=0 ; i<depth ; i++)
821 sb.append (' ') ;
822
823 sb.append ("</" + e.getNodeName () + ">");
824 }
825 }
826}
Note: See TracBrowser for help on using the repository browser.