title: Speeding up xpath
body: <p>I have a 1000 entry document whose format is something like:</p>
  <pre><code>&lt;Example&gt;
       &lt;Entry&gt;
            &lt;n1&gt;&lt;/n1&gt;
            &lt;n2&gt;&lt;/n2&gt;
        &lt;/Entry&gt;
        &lt;Entry&gt;
            &lt;n1&gt;&lt;/n1&gt;
            &lt;n2&gt;&lt;/n2&gt;
        &lt;/Entry&gt;
        &lt;!--and so on--&gt;
  </code></pre>
  <p>There are more than 1000 Entry nodes here. I am writing a Java program which basically gets all the node one by one and do some analyzing on each node. But the problem is that the retrieval time of the nodes increases with its no. For example it takes 78 millisecond to retrieve the first node 100 ms to retrieve the second and it keeps on increasing. And to retrieve the 999 node it takes more than 5 second. This is extremely slow. We would be plugging this code to XML files which have even more than 1000 entries. Some like millions. The total time to parse the whole document is more than 5 minutes.</p>
  <p>I am using this simple code to traverse it. Here <code>nxp</code> is my own class which has all the methods to get nodes from xpath.</p>
  <pre><code>nxp.fromXpathToNode(&quot;/Example/Entry&quot; + &quot;[&quot; + i  + &quot;]&quot;, doc);    
  </code></pre>
  <p>and <code>doc</code> is the document for the file. <code>i</code> is the no of node to retrieve.</p>
  <p>Also when i try something like this</p>
  <pre><code>List&lt;Node&gt; nl = nxp.fromXpathToNodes(&quot;/Example/Entry&quot;,doc);  
        content = nl.get(i);    
  </code></pre>
  <p>I face the same problem.</p>
  <p>Anyone has any solution on how to speed up the tretirival of the nodes, so it takes the same amount of time to get the 1st node as well as the 1000 node from the XML file.</p>
  <hr />
  <p>Here is the code for xpathtonode.</p>
  <pre><code>public Node fromXpathToNode(String expression, Node context)  
  {  
      try  
      {  
          return (Node)this.getCachedExpression(expression).evaluate(context, XPathConstants.NODE);  
      }  
      catch (Exception cause)  
      {  
          throw new RuntimeException(cause);  
      }  
  }  
  </code></pre>
  <p>and here is the code for fromxpathtonodes.</p>
  <pre><code>public List&lt;Node&gt; fromXpathToNodes(String expression, Node context)  
  {  
      List&lt;Node&gt; nodes = new ArrayList&lt;Node&gt;();  
      NodeList results = null;  
      
      try  
      {  
          results = (NodeList)this.getCachedExpression(expression).evaluate(context, XPathConstants.NODESET);  
            
          for (int index = 0; index &lt; results.getLength(); index++)  
          {  
              nodes.add(results.item(index));  
          }  
      }  
      catch (Exception cause)  
      {  
          throw new RuntimeException(cause);  
      }  
      
      return nodes;  
  }  
  </code></pre>
  <p>and here is the starting</p>
  <pre><code>public class NativeXpathEngine implements XpathEngine  
  {      
  private final XPathFactory factory;  
    
  private final XPath engine;  
  
  /**
   * Cache for previously compiled XPath expressions. {@link XPathExpression#hashCode()}
   * is not reliable or consistent so use the textual representation instead.
   */  
  private final Map&lt;String, XPathExpression&gt; cachedExpressions;  
    
  public NativeXpathEngine()  
  {
      super();  
      
      this.factory = XPathFactory.newInstance();  
      this.engine = factory.newXPath();  
      this.cachedExpressions = new HashMap&lt;String, XPathExpression&gt;();  
  }  
  </code></pre>