[Xml-logilab] XPathVisualizer patch

Matthew L Daniel mdaniel@scdi.com
Thu, 5 Sep 2002 13:46:30 -0400


--SLDf9lqlvOQaIe6s
Content-Type: text/plain; charset=us-ascii
Content-Disposition: inline

I really enjoyed your project and the fact that you made it OpenSource.
I found only one missing piece of functionality that I wanted in an
XPath tool, which is the ability to select the node and have the XPath
built for me. Since you were kind enough to OpenSource your project, I
was able to implement my "toy".

I had some compilation problems because I did not have Xerces DOMParser
on my machine (I have Xerces2 2.0.2 and JDK 1.4.0), so I tossed in a
DocumentLoaderFactory that made it work great for me. I also love Ant
build scripts, so I made one of those, too.

I hope you enjoy these changes and that others may benefit from them as
well. I give your organization complete rights over my changes,
including removing the attribution from my new classes. I just like
making it work, I do not require credit.

  Thank you,
  -- /v\atthew
-- 
Matthew L Daniel          The intellect is not a serious thing, and 
mdaniel@scdi.com          never has been. It is an instrument on 
http://MatthewDaniel.com/ which one plays, that is all. -- Oscar Wilde

--SLDf9lqlvOQaIe6s
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment; filename="xpath_visualizer_1_0_1.patch"

diff -ruN xpath_visualizer_1_0_orig/build.xml xpath_visualizer_1_0/build.xml
--- xpath_visualizer_1_0_orig/build.xml	1969-12-31 19:00:00.000000000 -0500
+++ xpath_visualizer_1_0/build.xml	2002-09-05 12:47:09.000000000 -0400
@@ -0,0 +1,33 @@
+<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
+<project default="compile" basedir=".">
+    <path id="xml.class.path">
+        <pathelement location="${jaxp.jar}" />
+        <pathelement location="${xercesImpl.jar}" />
+    </path>
+
+    <target name="compile">
+        <mkdir dir="classes" />
+        <javac srcdir="src" destdir="classes">
+            <classpath refid="xml.class.path" />
+        </javac>
+    </target>
+
+    <target name="jar">
+        <jar jarfile="bin/xpathVis.jar" manifest="src/main.mf">
+            <fileset dir="classes" includes="**/*.class" />
+            <fileset dir="src" includes="org/**/*.gif" />
+        </jar>
+    </target>
+
+    <target name="javadoc">
+        <javadoc 
+            sourcepath="src"
+            destdir="src/apiDocs"
+            windowtitle="XPath Visualizer 1.0"
+            packagenames="org.logilab.xml.tools,org.logilab.utils" />
+    </target>
+
+    <target name="clean">
+        <delete dir="classes" />
+    </target>
+</project>
diff -ruN xpath_visualizer_1_0_orig/src/main.mf xpath_visualizer_1_0/src/main.mf
--- xpath_visualizer_1_0_orig/src/main.mf	1969-12-31 19:00:00.000000000 -0500
+++ xpath_visualizer_1_0/src/main.mf	2002-09-05 12:43:41.000000000 -0400
@@ -0,0 +1,2 @@
+Class-Path: xercesImpl.jar xalan.jar jaxp-api.jar sax.jar dom.jar
+Main-Class: org.logilab.xml.tools.XPathVisualizer
diff -ruN xpath_visualizer_1_0_orig/src/org/logilab/xml/tools/DOMDocumentLoader.java xpath_visualizer_1_0/src/org/logilab/xml/tools/DOMDocumentLoader.java
--- xpath_visualizer_1_0_orig/src/org/logilab/xml/tools/DOMDocumentLoader.java	2001-07-26 12:47:08.000000000 -0400
+++ xpath_visualizer_1_0/src/org/logilab/xml/tools/DOMDocumentLoader.java	2002-09-05 13:36:18.000000000 -0400
@@ -34,7 +34,7 @@
 /**
  * This class provides an interface to a DOM parser
  */
-public class DOMDocumentLoader
+public class DOMDocumentLoader implements DocumentLoader
 {
     /** The parser used by this class */
     private DOMParser domParser;
diff -ruN xpath_visualizer_1_0_orig/src/org/logilab/xml/tools/DocumentLoader.java xpath_visualizer_1_0/src/org/logilab/xml/tools/DocumentLoader.java
--- xpath_visualizer_1_0_orig/src/org/logilab/xml/tools/DocumentLoader.java	1969-12-31 19:00:00.000000000 -0500
+++ xpath_visualizer_1_0/src/org/logilab/xml/tools/DocumentLoader.java	2002-09-05 13:36:14.000000000 -0400
@@ -0,0 +1,38 @@
+package org.logilab.xml.tools;
+
+import java.io.IOException;
+import java.io.File;
+import org.w3c.dom.Document;
+import org.xml.sax.SAXException;
+
+/**
+ * The required functionality to pull a Document out of the File specified.
+ *
+ * @author <a href="mailto:mdaniel@scdi.com">Matthew L Daniel</a>
+ */
+public interface DocumentLoader
+{
+    /**
+     * Reads the XML file named docFileName and returns the DOM document node.
+     * @param docFileName the name of the file.
+     * @param ignoreWhiteSpaces when true, the parser will exclude ignorable
+     * whitespaces text nodes.
+     * @return the document node of the file.
+     * @exception org.xml.sax.SAXException Throws parser SAX Exception.
+     * @exception java.io.IOException Throws parser I/O Exception.
+     */
+    public Document load(String docFileName, boolean ignoreWhiteSpaces) 
+        throws IOException, SAXException;
+
+    /**
+     * Reads the XML file referred by docFile and returns the DOM document node.
+     * @param docFile the file.
+     * @param ignoreWhiteSpaces when true, the parser will exclude ignorable
+     * whitespaces text nodes.
+     * @return the document node of the file.
+     * @exception org.xml.sax.SAXException Throws parser SAX Exception.
+     * @exception java.io.IOException Throws parser I/O Exception.
+     */
+    public Document load(File file, boolean ignoreWhiteSpaces)
+        throws IOException, SAXException;
+}
diff -ruN xpath_visualizer_1_0_orig/src/org/logilab/xml/tools/DocumentLoaderConfigurationException.java xpath_visualizer_1_0/src/org/logilab/xml/tools/DocumentLoaderConfigurationException.java
--- xpath_visualizer_1_0_orig/src/org/logilab/xml/tools/DocumentLoaderConfigurationException.java	1969-12-31 19:00:00.000000000 -0500
+++ xpath_visualizer_1_0/src/org/logilab/xml/tools/DocumentLoaderConfigurationException.java	2002-09-05 13:36:07.000000000 -0400
@@ -0,0 +1,61 @@
+package org.logilab.xml.tools;
+
+/**
+ * This is thrown when a DocumentLoaderFactory can't create a new DocumentLoader.
+ * @author <a href="mailto:mdaniel@scdi.com">Matthew L Daniel</a>
+ */
+public class DocumentLoaderConfigurationException extends Exception
+{
+    /**
+     * The default constructor. This method should not be used, since it 
+     * does not convey why the exception was thrown.
+     */
+    public DocumentLoaderConfigurationException() 
+    {
+        super();
+        cause = null;
+    }
+
+    /**
+     * Allows the exception to carry some description of the cause of failure.
+     * @param message A description of what went wrong
+     */
+    public DocumentLoaderConfigurationException(String message) 
+    {
+        super(message);
+        cause = null;
+    }
+
+    /**
+     * Allows the exception to carry lots of context about the reason for failure.
+     * @param message A description of what went wrong
+     * @param ex A Throwable that caused this Exception
+     */
+    public DocumentLoaderConfigurationException(String message, Throwable ex) 
+    {
+        super(message);
+        cause = ex;
+    }
+
+    /**
+     * Allows the exception to carry context about the failure.  This method
+     * should not be used as it does not provide human readable text.
+     *@param ex A Throwable that caused this Exception
+     */
+    public DocumentLoaderConfigurationException(Throwable ex) 
+    {
+        cause = ex;
+    }
+
+    /**
+     * Gets the root cause of this exception if one exists.
+     * @return The root throwable or null if there wasn't one.
+     */
+    public Throwable getCause() 
+    {
+        return cause;
+    }
+
+    /** The optional root cause of this exception. */
+    private Throwable cause;
+}
diff -ruN xpath_visualizer_1_0_orig/src/org/logilab/xml/tools/DocumentLoaderFactory.java xpath_visualizer_1_0/src/org/logilab/xml/tools/DocumentLoaderFactory.java
--- xpath_visualizer_1_0_orig/src/org/logilab/xml/tools/DocumentLoaderFactory.java	1969-12-31 19:00:00.000000000 -0500
+++ xpath_visualizer_1_0/src/org/logilab/xml/tools/DocumentLoaderFactory.java	2002-09-05 13:36:17.000000000 -0400
@@ -0,0 +1,55 @@
+package org.logilab.xml.tools;
+
+import java.io.IOException;
+import java.io.File;
+import org.w3c.dom.Document;
+import org.xml.sax.SAXException;
+
+/**
+ * Creates the best DocumentLoader based on your system.
+ *@author <a href="mailto:mdaniel@scdi.com">Matthew L Daniel</a>
+ */
+public class DocumentLoaderFactory
+{
+    /**
+     * Creates a new <code>DocumentLoaderFactory</code>. This is modeled after
+     * the other Sun Factory patterns. As a side note, it also implements the
+     * Singleton pattern.
+     */
+    public static DocumentLoaderFactory newInstance() 
+    {
+        if( self == null ) {
+            self = new DocumentLoaderFactory();
+        }
+        return self;
+    }
+
+    /**
+     * Creates a new DocumentLoader that works best with your system.
+     * @see JAXPDocumentLoader
+     * @see DOMDocumentLoader
+     */
+    public DocumentLoader newDocumentLoader() 
+        throws DocumentLoaderConfigurationException
+    {
+        try {
+            Class.forName("javax.xml.parsers.DocumentBuilder");
+            return new JAXPDocumentLoader();
+        } catch( ClassNotFoundException cnfe ) {
+            // eat it
+        }
+        try {
+            Class.forName("org.apache.xerces.parsers.DOMParser");
+            return new DOMDocumentLoader();
+        } catch( ClassNotFoundException cnfe ) {
+            // eat it
+        }
+        throw new DocumentLoaderConfigurationException(
+                "Can't find JAXP or DOMPaser in your CLASSPATH.");
+    }
+
+    /** Use <code>DocumentLoaderFactory.newInstance()</code> instead. */
+    private DocumentLoaderFactory() {}
+
+    private static DocumentLoaderFactory self;
+}
diff -ruN xpath_visualizer_1_0_orig/src/org/logilab/xml/tools/JAXPDocumentLoader.java xpath_visualizer_1_0/src/org/logilab/xml/tools/JAXPDocumentLoader.java
--- xpath_visualizer_1_0_orig/src/org/logilab/xml/tools/JAXPDocumentLoader.java	1969-12-31 19:00:00.000000000 -0500
+++ xpath_visualizer_1_0/src/org/logilab/xml/tools/JAXPDocumentLoader.java	2002-09-05 13:36:25.000000000 -0400
@@ -0,0 +1,40 @@
+package org.logilab.xml.tools;
+
+import java.io.IOException;
+import java.io.File;
+import javax.xml.parsers.DocumentBuilder;
+import javax.xml.parsers.DocumentBuilderFactory;
+import javax.xml.parsers.ParserConfigurationException;
+import org.w3c.dom.Document;
+import org.xml.sax.SAXException;
+
+public class JAXPDocumentLoader implements DocumentLoader
+{
+    private DocumentBuilderFactory dbf;
+    private DocumentBuilder db;
+
+    public JAXPDocumentLoader()
+    {
+        try {
+            dbf = DocumentBuilderFactory.newInstance();
+            db = dbf.newDocumentBuilder();
+        } catch( ParserConfigurationException pce ) {
+            pce.printStackTrace(System.err);
+        }
+    }
+
+    public Document load(String file, boolean ws)
+        throws IOException, SAXException
+    {
+        return load(new File(file),ws);
+    }
+
+    public Document load(File file, boolean ws)
+        throws IOException, SAXException
+    {
+        if( db == null ) {
+            throw new NullPointerException("DocumentBuilder is null");
+        }
+        return db.parse(file);
+    }
+}
diff -ruN xpath_visualizer_1_0_orig/src/org/logilab/xml/tools/VisualizerGUI.java xpath_visualizer_1_0/src/org/logilab/xml/tools/VisualizerGUI.java
--- xpath_visualizer_1_0_orig/src/org/logilab/xml/tools/VisualizerGUI.java	2001-07-26 17:59:26.000000000 -0400
+++ xpath_visualizer_1_0/src/org/logilab/xml/tools/VisualizerGUI.java	2002-09-05 13:36:27.000000000 -0400
@@ -34,6 +34,7 @@
 
 import java.awt.event.ActionListener;
 import java.awt.event.ActionEvent;
+import java.awt.event.KeyEvent;
 
 import javax.swing.JPanel;
 import javax.swing.JFrame;
@@ -77,7 +78,7 @@
 import org.logilab.xml.tools.DOMTreeRenderer;
 import org.logilab.xml.tools.DOMTreeModel;
 import org.logilab.xml.tools.XPathEvaluator;
-import org.logilab.xml.tools.DOMDocumentLoader;
+import org.logilab.xml.tools.DocumentLoader;
 
 import org.logilab.utils.ExtFileFilter;
 
@@ -120,8 +121,8 @@
 
     /** XPathEvaluator used here.*/
     private XPathEvaluator xpathEvaluator;
-    /** DOMDocumentLoader used here.*/
-    private DOMDocumentLoader documentLoader;
+    /** DocumentLoader used here.*/
+    private DocumentLoader documentLoader;
 
     /** icon of this window.*/
     private ImageIcon windowIcon;
@@ -130,10 +131,10 @@
      * Builds the main window of the application. When created, no XML document
      * is loaded and thus no document tree is displayed.
      * @param xpathEngine the XPathEvaluator used here.
-     * @param docLoader the DOMDocumentLoader used here.
+     * @param docLoader the DocumentLoader used here.
      */
     public VisualizerGUI(XPathEvaluator xpathEngine,
-			 DOMDocumentLoader docLoader)
+			 DocumentLoader docLoader)
     {
 	// Builds parent.
 	super();
@@ -148,7 +149,7 @@
 	setIconImage(windowIcon.getImage());
 	setTitle("XPath Visualizer");
 
-	// Stocks XPathEvaluator and DOMDocumentLoader.
+	// Stocks XPathEvaluator and DocumentLoader.
 	xpathEvaluator = xpathEngine;
 	documentLoader = docLoader;
 	
@@ -320,25 +321,31 @@
 
 	// Builds the file menu.
 	JMenu docMenu = new JMenu("File");
+    docMenu.setMnemonic(KeyEvent.VK_F);
 	JMenuItem loadMIt = new JMenuItem("Load document");
 	loadMIt.setActionCommand("LOAD_FILE_DOCUMENT");
 	loadMIt.addActionListener(this);
+    loadMIt.setMnemonic(KeyEvent.VK_L);
 	docMenu.add(loadMIt);
 	stripChMIt = new JCheckBoxMenuItem("Strip of whitespaces");
+    stripChMIt.setMnemonic(KeyEvent.VK_S);
 	docMenu.add(stripChMIt);
 	docMenu.addSeparator();
 	JMenuItem quitMIt = new JMenuItem("Quit");
 	quitMIt.setActionCommand("QUIT");
 	quitMIt.addActionListener(this);
+    quitMIt.setMnemonic(KeyEvent.VK_Q);
 	docMenu.add(quitMIt);
 	menu.add(docMenu);
 
 	// Builds the help menu.
 	JMenu helpMenu = new JMenu("Help");
+    helpMenu.setMnemonic(KeyEvent.VK_H);
 	helpMenu.addSeparator();
 	JMenuItem aboutMIt = new JMenuItem("About XPath Visualizer");
 	aboutMIt.setActionCommand("ABOUT");
 	aboutMIt.addActionListener(this);
+    aboutMIt.setMnemonic(KeyEvent.VK_A);
 	helpMenu.add(aboutMIt);
 	menu.add(helpMenu);
 
@@ -419,6 +426,8 @@
 	
 	if (treeModel != null)
 	{
+        XPathTreeClickHandler clickHandler = new XPathTreeClickHandler();
+        clickHandler.setUpdateComponent(xpathField);
 	    // Builds a new document tree.
 	    docTree = new JTree(treeModel);
 	    docTree.setEditable(false);
@@ -426,6 +435,8 @@
 	    docTree.getSelectionModel().
 		setSelectionMode(TreeSelectionModel.SINGLE_TREE_SELECTION);
 	    docTree.setCellRenderer(docTreeRenderer);
+        docTree.addTreeSelectionListener(clickHandler);
+        docTree.addMouseListener(clickHandler);
 	    ToolTipManager.sharedInstance().registerComponent(docTree);
 
 	    // Adds tree source in window title.
@@ -512,8 +523,13 @@
 	    // Erases the result panel content and sets instead a new 
 	    // JTree containing the node set.
 	    result.removeAll();
-	    resTreeModel = new DOMTreeModel
-		                  (((XNodeSet)xpathResult).mutableNodeset());
+        try {
+            resTreeModel = new DOMTreeModel
+		                  (((XNodeSet)xpathResult).nodelist());
+        } catch( TransformerException te ) {
+            te.printStackTrace(System.err);
+            break;
+        }
 	    resTree = new JTree(resTreeModel);
 	    resTree.setEditable(false);
 	    resTree.putClientProperty("JTree.lineStyle", "Angled");
@@ -646,7 +662,7 @@
 
 	    try
 	    {
-		// Gets DOM Document Node from file with the DOMDocumentLoader
+		// Gets DOM Document Node from file with the DocumentLoader
 		Document newDOMDoc = documentLoader.load(newDocFile,
 						     stripChMIt.getState());
 
@@ -702,7 +718,7 @@
 	    if (xpathResult.getType() == XObject.CLASS_NODESET)
 	    {
 		docTreeRenderer.setHighlightedNodes
-		                         (xpathResult.mutableNodeset());
+		                         (xpathResult.nodelist());
 	    }
 
 	    // Casts the XPath result to the type asked by the user.
diff -ruN xpath_visualizer_1_0_orig/src/org/logilab/xml/tools/XPathTreeClickHandler.java xpath_visualizer_1_0/src/org/logilab/xml/tools/XPathTreeClickHandler.java
--- xpath_visualizer_1_0_orig/src/org/logilab/xml/tools/XPathTreeClickHandler.java	1969-12-31 19:00:00.000000000 -0500
+++ xpath_visualizer_1_0/src/org/logilab/xml/tools/XPathTreeClickHandler.java	2002-09-05 13:36:30.000000000 -0400
@@ -0,0 +1,150 @@
+package org.logilab.xml.tools;
+
+import java.awt.event.MouseAdapter;
+import java.awt.event.MouseEvent;
+import javax.swing.event.TreeSelectionListener;
+import javax.swing.event.TreeSelectionEvent;
+import javax.swing.tree.TreePath;
+import javax.swing.text.JTextComponent;
+import org.w3c.dom.Node;
+
+/** 
+ * Implements XPath building and copying into a JTextComponent.
+ * Handles both TreeSelectionEvents and mouse clicks in order to build XPaths
+ * based on the selected tree element then set the text of the specified
+ * JTextComponent upon right-click.
+ *
+ * @author <a href="mailto:mdaniel@scdi.com">Matthew L Daniel</a>
+ */
+public class XPathTreeClickHandler 
+    extends MouseAdapter
+    implements TreeSelectionListener
+{
+
+    /**
+     * Returns the generated XPath or null if none has been constructed.
+     * This is built in <code>valueChanged(TreeSelectionEvent)</code>.
+     */
+    public String getXpath() {
+        return xpath;
+    }
+
+    /**
+     * Indicates the JTextComponent you want updated when they right-click on
+     * a tree element.
+     * @see #valueChanged(TreeSelectionEvent)
+     */
+    public void setUpdateComponent(JTextComponent jtc) {
+        textField = jtc;
+    }
+
+    /** 
+     * Updates the JTextComponent with the generated XPath if the mouse-click
+     * is a right-click. If the event is not BUTTON3, the JTextComponent is
+     * null, or the generated XPath is null, no action is taken.
+     * @param me The event generated by the mouse click.
+     * @see #getXpath()
+     */
+    public void mouseClicked(MouseEvent me) 
+    {
+        int button = me.getButton();
+        if( button == MouseEvent.BUTTON3 ) {
+            if( textField != null ) {
+                if( xpath != null) {
+                    textField.setText(xpath);
+                } else {
+                    System.err.println(
+                            "Skipping field update because XPath is null");
+                }
+            } else {
+                System.err.println(
+                        "Skipping field update because field is null");
+            }
+        }
+    }
+
+    /**
+     * Builds the XPath for the tree-element (a <code>org.w3c.dom.Node</code>)
+     * that is selected (firing this event). If the selected tree-element is
+     * not a <code>Node</code>, this will set the generated xpath to <tt>/</tt>
+     * and return.
+     * @param tse The event that is generated by the user selecting a tree element.
+     * @see org.w3c.dom.Node
+     * @see #getXpath()
+     */
+    public void valueChanged(TreeSelectionEvent tse)
+    {
+        TreePath path = tse.getPath();
+        Object[] o = path.getPath();
+        StringBuffer sb = new StringBuffer();
+        for(int i = 0; i < o.length; i++) {
+            Node node = null;
+            try {
+                // The O'Reilly book on Java performance says that catching
+                // ClassCastExceptions is faster than using instanceof
+                node = (Node)o[i];
+            } catch( ClassCastException cce ) {
+                System.err.println("ERROR: Tree element is not a Node.");
+                // don't let this throw NullPointerExceptions
+                if( xpath == null ) {
+                    xpath = "/";
+                }
+                return;
+            }
+            String prefix = node.getPrefix();
+            String name = node.getNodeName();
+            if( prefix == null ) prefix = "";
+            short node_type = node.getNodeType();
+            switch( node_type ) {
+                // skip document's in the XPath
+                case Node.DOCUMENT_NODE:
+                    // fall-through
+                // you can't XPath to text, only the containing element
+                case Node.TEXT_NODE:
+                    continue;
+                case Node.ELEMENT_NODE:
+                    boolean needsSelector = false;
+                    int above = 1;
+                    sb.append('/')
+                        .append(prefix)
+                        .append(name);
+                    Node n = node.getPreviousSibling(); 
+                    while( n != null ) {
+                        if( n.getNodeName().equals(name) ) {
+                            needsSelector = true;
+                            above++;
+                        }
+                        n = n.getPreviousSibling(); 
+                    }
+                    if( !needsSelector ) {
+                        n = node.getNextSibling();
+                        while( n != null ) {
+                            if( n.getNodeName().equals(name) ) {
+                                needsSelector = true;
+                                break;
+                            }
+                            n = n.getNextSibling();
+                        }
+                    }
+                    if( needsSelector ) {
+                        sb.append('[').append(above).append(']');
+                    }
+                    break;
+                case Node.ATTRIBUTE_NODE:
+                    sb.append('/')
+                        .append('@')
+                        .append(name);
+                    break;
+                default:
+                    System.err.println("Node.type: "+node_type);
+            }
+        }
+//        System.out.println("XPath="+sb);
+        xpath = sb.toString();
+    }
+
+    /** The constructed XPath. */
+    private String xpath;
+    /** The JTextComponent that should be updated on right-click. */
+    private JTextComponent textField;
+}
diff -ruN xpath_visualizer_1_0_orig/src/org/logilab/xml/tools/XPathVisualizer.java xpath_visualizer_1_0/src/org/logilab/xml/tools/XPathVisualizer.java
--- xpath_visualizer_1_0_orig/src/org/logilab/xml/tools/XPathVisualizer.java	2001-07-26 17:56:10.000000000 -0400
+++ xpath_visualizer_1_0/src/org/logilab/xml/tools/XPathVisualizer.java	2002-09-05 13:36:32.000000000 -0400
@@ -31,7 +31,9 @@
 
 import org.logilab.xml.tools.DOMTreeModel;
 import org.logilab.xml.tools.XPathEvaluator;
-import org.logilab.xml.tools.DOMDocumentLoader;
+import org.logilab.xml.tools.DocumentLoader;
+import org.logilab.xml.tools.DocumentLoaderFactory;
+import org.logilab.xml.tools.DocumentLoaderConfigurationException;
 import org.logilab.xml.tools.VisualizerGUI;
 
 /**
@@ -42,8 +44,8 @@
 {
     /** the XPathEvaluator used in the application. */
     private XPathEvaluator xpathEval;
-    /** the DOMDocumentLoader used in the application. */
-    private DOMDocumentLoader docLoad;
+    /** the DocumentLoader used in the application. */
+    private DocumentLoader docLoad;
     /** the main window. */
     private VisualizerGUI mainFrame;
 
@@ -53,7 +55,12 @@
     public XPathVisualizer()
     {
 	xpathEval = new XPathEvaluator();
-	docLoad = new DOMDocumentLoader();
+    try {
+        docLoad = DocumentLoaderFactory.newInstance().newDocumentLoader();
+    } catch( DocumentLoaderConfigurationException dlce ) {
+        System.err.println("Can't load your document: "+dlce);
+        return;
+    }
         mainFrame = new VisualizerGUI(xpathEval,docLoad);
 
         mainFrame.addWindowListener

--SLDf9lqlvOQaIe6s--