Index: /gli/trunk/src/org/greenstone/gatherer/util/XMLTools.java
===================================================================
--- /gli/trunk/src/org/greenstone/gatherer/util/XMLTools.java	(revision 15580)
+++ /gli/trunk/src/org/greenstone/gatherer/util/XMLTools.java	(revision 15581)
@@ -372,4 +372,5 @@
     } // getLocationString(SAXParseException):String
 
+
     /** Parse an XML document from a given file path */
     static public Document parseXMLFile (String xml_file_path, boolean use_class_loader) {
@@ -424,10 +425,36 @@
     /** Parse an XML document from a given reader */
     static public Document parseXML (Reader xml_reader) {
-        Document document = null;
-        
-        try {
+	// If debugging, the following will store the XML contents to be parsed, 
+	// which can then be inspected upon encountering a SAXException (need to run GLI with -debug on)
+	String xmlContents = "";
+
+	Document document = null;
+	try {
+	    // (1) In case parsing exceptions are thrown (SAX Exceptions), we want to get some
+	    // idea of where things went wrong. This will print the "XML" contents to either
+	    // system.out (if debugging is off) or to the DebugStream otherwise.
+	    // We need to read the XML twice to know the line where things went wrong, so
+	    // do the additional reading only if we're debugging 
+	    if(DebugStream.isDebuggingEnabled()) { 		
+		StringBuffer buf = new StringBuffer();
+		char[] buffer = new char[500];
+		int numCharsRead = xml_reader.read(buffer, 0, buffer.length); 
+		while(numCharsRead != -1) {
+		    buf.append(buffer, 0, numCharsRead);
+		    numCharsRead = xml_reader.read(buffer, 0, buffer.length); 
+		}
+		xmlContents = buf.toString();
+		xml_reader.close(); // closing the old Reader
+		xml_reader = null;
+		buffer = null;
+		buf = null;
+		// we need a Reader to parse the same contents as the Reader that was just closed
+		xml_reader = new StringReader(xmlContents);
+	    }
+	    
+	    // (2) The actual XML parsing
             InputSource isc       = new InputSource (xml_reader);
-            DOMParser parser      = new DOMParser ();
-            parser.setFeature ("http://xml.org/sax/features/validation", false);
+	    DOMParser parser      = new DOMParser ();
+	    parser.setFeature ("http://xml.org/sax/features/validation", false);
             parser.setFeature ("http://apache.org/xml/features/nonvalidating/load-external-dtd", false);
             // May or may not be ignored, the documentation for Xerces is contradictory. If it works then parsing -should- be faster.
@@ -436,8 +463,19 @@
             parser.parse (isc);
             document = parser.getDocument ();
-        }
-        catch (SAXException exception) {
-            System.err.println ("SAX exception: " + exception.getMessage ());
-            DebugStream.printStackTrace (exception);
+        
+	} catch(SAXParseException e) {
+	    showXMLParseFailureLine(e, xmlContents);
+	} catch (SAXException exception) {
+	    System.err.println ("SAX exception: " + exception.getMessage ());
+	    if(DebugStream.isDebuggingEnabled()) {
+		DebugStream.println("Encountered a SAX exception when parsing the following:\n*********START\n" 
+				    + xmlContents + "\n************END\n");
+		// Exit to let the user view the erroneous line/xml before it goes past the screen buffer?
+		DebugStream.println("Debug mode: Exiting the program as there was trouble parsing the XML..."); 
+		System.exit(-1);
+	    } 
+	    // else, not running in debug mode, so don't exit after exception  
+	    System.out.println("***Turn debugging on (run GLI with -debug) to view the XML contents that could not be parsed.");
+	    DebugStream.printStackTrace (exception);
         }
         catch (Exception exception) {
@@ -447,5 +485,40 @@
         return document;
     }
-    
+
+    /** Displays the line (string) where the SAXParseException occurred, given a String of the 
+     * entire xml that was being parsed and the SAXParseException object that was caught. 
+     * The messages are printed to DebugStream, so run GLI/FLI with -debug to view this output. 
+     * @param xmlContents is the entire xml that was being parsed when the exception occurred
+     * @param e is the SAXParseException object that was thrown upon parsing the xmlContents.
+     */
+    public static void showXMLParseFailureLine(SAXParseException e, String xmlContents) {
+	// the actual line (String literal) where parsing failed and the SAXParseException occurred.
+	String line = "";
+	int linenumber = e.getLineNumber();
+	DebugStream.println("\n****SAXParseException on LINE NUMBER: " + linenumber);
+	if(DebugStream.isDebuggingEnabled()) {
+	    if(linenumber != -1) { 
+		// find the line in xmlContents string (xmlContents is only set if GLI is run with debugging turned on)
+		int start = 0;
+		int end = xmlContents.length();
+		for(int i = 1; i <= linenumber; i++) {
+		    end = xmlContents.indexOf("\n");
+		    line = xmlContents.substring(start, end);
+		    start = end+1;
+		}
+		DebugStream.println("The parsing error occurred on this line:\n***********START\n" + line + "\n***********END");
+		DebugStream.println("SAXParseException message: " + e.getMessage() + "\n");
+	    } else { // no particular line number, print out all the xml so debugger can inspect it
+		DebugStream.println("Encountered a SAX exception when parsing the following:\n*********START\n" 
+				    + xmlContents + "\n************END\n");
+	    }
+	    // Exit to let the user view the erroneous line/xml before it goes past the screen buffer?
+	    DebugStream.println("\nDebug mode: Exiting the program as there was trouble parsing the XML..."); 
+	    System.exit(-1);
+	} else { // not running in debug mode
+	    System.out.println("***Turn debugging on (run GLI with -debug) to view the XML contents/line that could not be parsed.");
+	}
+    }
+
     
     static public StringBuffer readXMLStream (InputStream input_stream) {
@@ -735,7 +808,4 @@
             sb.append ("</" + e.getNodeName () + ">");
         }
-        
-        
-    }
-    
+    }
 }
