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

Last change on this file since 16988 was 16988, checked in by kjdon, 16 years ago

added xmlNodeToStringWithoutIndenting for use with format statements for gs3, so don't get more and more spaces added in each time its saved

  • Property svn:keywords set to Author Date Id Revision
File size: 31.4 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 if (nonEscapingTagNames != null) {
627 f.setNonEscapingElements (nonEscapingTagNames);
628 }
629 // Create the necessary writer stream for serialization.
630 OutputStreamWriter osw = new OutputStreamWriter (os, "UTF-8");
631 Writer w = new BufferedWriter (osw);
632 // Generate a new serializer from the above.
633 XMLSerializer s = new XMLSerializer (w, f);
634 s.asDOMSerializer ();
635 // Finally serialize the document to file.
636 s.serialize (document);
637 // And close.
638 os.close ();
639 }
640 catch (Exception exception) {
641 DebugStream.printStackTrace (exception);
642 }
643 }
644
645 /** Write an XML document to a given file */
646 static public void writeXMLFile (File xml_file, Document document) {
647 writeXMLFile(xml_file, document, null);
648 }
649
650 public static void printXMLNode (Node e) {
651 printXMLNode (e, 0) ;
652 }
653
654 public static void printXMLNode (Node e, int depth) { //recursive method call using DOM API...
655
656 for (int i=0 ; i<depth ; i++)
657 System.out.print (' ') ;
658
659 if (e.getNodeType () == Node.TEXT_NODE){
660 //System.out.println("text") ;
661 if (e.getNodeValue () != "") {
662 System.out.println (e.getNodeValue ()) ;
663 }
664 return ;
665 }
666
667 System.out.print ('<');
668 System.out.print (e.getNodeName ());
669 NamedNodeMap attrs = e.getAttributes ();
670 if (attrs != null) {
671 for (int i = 0; i < attrs.getLength (); i++) {
672 Node attr = attrs.item (i);
673 System.out.print (' ');
674 System.out.print (attr.getNodeName ());
675 System.out.print ("=\"");
676 System.out.print (attr.getNodeValue ());
677 System.out.print ('"');
678 }
679 }
680 NodeList children = e.getChildNodes ();
681
682 if (children == null || children.getLength () == 0)
683 System.out.println ("/>") ;
684 else {
685
686 System.out.println ('>') ;
687
688 int len = children.getLength ();
689 for (int i = 0; i < len; i++) {
690 printXMLNode (children.item (i), depth + 1);
691 }
692
693 for (int i=0 ; i<depth ; i++)
694 System.out.print (' ') ;
695
696 System.out.println ("</" + e.getNodeName () + ">");
697 }
698
699 }
700 public static String xmlNodeToString (Node e){
701 StringBuffer sb = new StringBuffer ("");
702 xmlNodeToString (sb,e,0);
703 return sb.toString ();
704 }
705
706 private static void xmlNodeToString (StringBuffer sb, Node e, int depth){
707
708 for (int i=0 ; i<depth ; i++)
709 sb.append (' ') ;
710
711 if (e.getNodeType () == Node.TEXT_NODE){
712 if (e.getNodeValue () != "") {
713 sb.append (e.getNodeValue ()) ;
714 }
715 return ;
716 }
717
718 sb.append ('<');
719 sb.append (e.getNodeName ());
720 NamedNodeMap attrs = e.getAttributes ();
721 if (attrs != null) {
722 for (int i = 0; i < attrs.getLength (); i++) {
723 Node attr = attrs.item (i);
724 sb.append (' ');
725 sb.append (attr.getNodeName ());
726 sb.append ("=\"");
727 sb.append (attr.getNodeValue ());
728 sb.append ('"');
729 }
730 }
731 NodeList children = e.getChildNodes ();
732
733 if (children == null || children.getLength () == 0)
734 sb.append ("/>\n") ;
735 else {
736
737 sb.append (">\n") ;
738
739 int len = children.getLength ();
740 for (int i = 0; i < len; i++) {
741 xmlNodeToString (sb,children.item (i), depth + 1);
742 }
743
744 for (int i=0 ; i<depth ; i++)
745 sb.append (' ') ;
746
747 sb.append ("</" + e.getNodeName () + ">\n");
748 }
749
750
751 }
752
753 public static String xmlNodeToStringWithoutIndenting (Node e) {
754 StringBuffer sb = new StringBuffer ("");
755 xmlNodeToStringWithoutNewline(sb, e, -1);
756 return sb.toString();
757 }
758 public static String xmlNodeToStringWithoutNewline (Node e){
759 StringBuffer sb = new StringBuffer ("");
760 xmlNodeToStringWithoutNewline (sb,e,0);
761 return sb.toString ();
762 }
763
764 private static void xmlNodeToStringWithoutNewline (StringBuffer sb, Node e, int depth){
765
766 for (int i=0 ; i<depth ; i++)
767 sb.append (' ') ;
768
769 if (e.getNodeType () == Node.TEXT_NODE){
770 if (e.getNodeValue () != "") {
771 sb.append (e.getNodeValue ()) ;
772 }
773 return ;
774 }
775
776 sb.append ('<');
777 sb.append (e.getNodeName ());
778 NamedNodeMap attrs = e.getAttributes ();
779 if (attrs != null) {
780 for (int i = 0; i < attrs.getLength (); i++) {
781 Node attr = attrs.item (i);
782 sb.append (' ');
783 sb.append (attr.getNodeName ());
784 sb.append ("=\"");
785 sb.append (attr.getNodeValue ());
786 sb.append ('"');
787 }
788 }
789 NodeList children = e.getChildNodes ();
790
791 if (children == null || children.getLength () == 0)
792 sb.append ("/>") ;
793 else {
794
795 sb.append (">") ;
796
797 int len = children.getLength ();
798 for (int i = 0; i < len; i++) {
799 if (depth >= 0) {
800 xmlNodeToStringWithoutNewline (sb,children.item (i), depth + 1);
801 } else {
802 xmlNodeToStringWithoutNewline (sb,children.item (i), depth);
803 }
804 }
805
806 for (int i=0 ; i<depth ; i++)
807 sb.append (' ') ;
808
809 sb.append ("</" + e.getNodeName () + ">");
810 }
811 }
812}
Note: See TracBrowser for help on using the repository browser.